<!doctype html>
<html class="no-js" lang="en" data-content_root="./">
  <head><meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="color-scheme" content="light dark"><meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="index" title="Index" href="genindex.html"><link rel="search" title="Search" href="search.html"><link rel="next" title="OSXPhotos Python Reference" href="reference.html"><link rel="prev" title="OSXPhotos Python Package Overview" href="package_overview.html">

    <!-- Generated with Sphinx 8.2.3 and Furo 2025.09.25 -->
        <title>OSXPhotos Python API - osxphotos 0.74.2 documentation</title>
      <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d111a655" />
    <link rel="stylesheet" type="text/css" href="_static/styles/furo.css?v=580074bf" />
    <link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
    <link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?v=8dab3a3b" />
    
    


<style>
  body {
    --color-code-background: #f2f2f2;
  --color-code-foreground: #1e1e1e;
  
  }
  @media not print {
    body[data-theme="dark"] {
      --color-code-background: #202020;
  --color-code-foreground: #d0d0d0;
  
    }
    @media (prefers-color-scheme: dark) {
      body:not([data-theme="light"]) {
        --color-code-background: #202020;
  --color-code-foreground: #d0d0d0;
  
      }
    }
  }
</style></head>
  <body>
    
    <script>
      document.body.dataset.theme = localStorage.getItem("theme") || "auto";
    </script>
    

<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="svg-toc" viewBox="0 0 24 24">
    <title>Contents</title>
    <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
      <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
    </svg>
  </symbol>
  <symbol id="svg-menu" viewBox="0 0 24 24">
    <title>Menu</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
      <line x1="3" y1="12" x2="21" y2="12"></line>
      <line x1="3" y1="6" x2="21" y2="6"></line>
      <line x1="3" y1="18" x2="21" y2="18"></line>
    </svg>
  </symbol>
  <symbol id="svg-arrow-right" viewBox="0 0 24 24">
    <title>Expand</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
      <polyline points="9 18 15 12 9 6"></polyline>
    </svg>
  </symbol>
  <symbol id="svg-sun" viewBox="0 0 24 24">
    <title>Light mode</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
      <circle cx="12" cy="12" r="5"></circle>
      <line x1="12" y1="1" x2="12" y2="3"></line>
      <line x1="12" y1="21" x2="12" y2="23"></line>
      <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
      <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
      <line x1="1" y1="12" x2="3" y2="12"></line>
      <line x1="21" y1="12" x2="23" y2="12"></line>
      <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
      <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
    </svg>
  </symbol>
  <symbol id="svg-moon" viewBox="0 0 24 24">
    <title>Dark mode</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
    </svg>
  </symbol>
  <symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
    <title>Auto light/dark, in light mode</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
      class="icon-custom-derived-from-feather-sun-and-tabler-moon">
      <path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
      <line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
      <line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
      <line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
      <line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
      <line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
      <line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
      <line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
      <line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
      <circle cx="14.5" cy="9.55" r="3.6"/>
    </svg>
  </symbol>
  <symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
    <title>Auto light/dark, in dark mode</title>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
      class="icon-custom-derived-from-feather-sun-and-tabler-moon">
      <path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
      <line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
      <line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
      <line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
      <line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
      <line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
      <line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
      <line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
      <line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
      <circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
    </svg>
  </symbol>
  <symbol id="svg-pencil" viewBox="0 0 24 24">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
      <path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
      <path d="M13.5 6.5l4 4" />
      <path d="M20 21l2 -2l-2 -2" />
      <path d="M17 17l-2 2l2 2" />
    </svg>
  </symbol>
  <symbol id="svg-eye" viewBox="0 0 24 24">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
      <path
        d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
      <path d="M20 21l2 -2l-2 -2" />
      <path d="M17 17l-2 2l2 2" />
    </svg>
  </symbol>
</svg>

<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation" aria-label="Toggle site navigation sidebar">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc" aria-label="Toggle table of contents sidebar">
<label class="overlay sidebar-overlay" for="__navigation"></label>
<label class="overlay toc-overlay" for="__toc"></label>

<a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>



<div class="page">
  <header class="mobile-header">
    <div class="header-left">
      <label class="nav-overlay-icon" for="__navigation">
        <span class="icon"><svg><use href="#svg-menu"></use></svg></span>
      </label>
    </div>
    <div class="header-center">
      <a href="index.html"><div class="brand">osxphotos 0.74.2 documentation</div></a>
    </div>
    <div class="header-right">
      <div class="theme-toggle-container theme-toggle-header">
        <button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
          <svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
          <svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
          <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
          <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
        </button>
      </div>
      <label class="toc-overlay-icon toc-header-icon" for="__toc">
        <span class="icon"><svg><use href="#svg-toc"></use></svg></span>
      </label>
    </div>
  </header>
  <aside class="sidebar-drawer">
    <div class="sidebar-container">
      
      <div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
  
  <span class="sidebar-brand-text">osxphotos 0.74.2 documentation</span>
  
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
  <input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
  <input type="hidden" name="check_keywords" value="yes">
  <input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
  <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">OSXPhotos Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos Python Reference</a></li>
</ul>

</div>
</div>

      </div>
      
    </div>
  </aside>
  <div class="main">
    <div class="content">
      <div class="article-container">
        <a href="#" class="back-to-top muted-link">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
          </svg>
          <span>Back to top</span>
        </a>
        <div class="content-icon-container">
          <div class="view-this-page">
  <a class="muted-link" href="_sources/API_README.rst.txt" title="View this page">
    <svg><use href="#svg-eye"></use></svg>
    <span class="visually-hidden">View this page</span>
  </a>
</div>
<div class="theme-toggle-container theme-toggle-content">
            <button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
              <svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
              <svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
              <svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
              <svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
            </button>
          </div>
          <label class="toc-overlay-icon toc-content-icon" for="__toc">
            <span class="icon"><svg><use href="#svg-toc"></use></svg></span>
          </label>
        </div>
        <article role="main" id="furo-main-content">
          <section id="osxphotos-python-api">
<h1>OSXPhotos Python API<a class="headerlink" href="#osxphotos-python-api" title="Link to this heading">¶</a></h1>
<p>In addition to a command line interface, OSXPhotos provides a access to a Python API that allows you to easily access a Photos library, often with just a few lines of code.</p>
<section id="table-of-contents">
<h2>Table of Contents<a class="headerlink" href="#table-of-contents" title="Link to this heading">¶</a></h2>
<ul class="simple">
<li><p><a class="reference external" href="#example-uses-of-the-python-package">Example uses of the Python package</a></p></li>
<li><p><a class="reference external" href="#building-simple-command-line-tools">Building simple command line tools</a></p></li>
<li><p><a class="reference external" href="#concurrency">Concurrency</a></p></li>
<li><p><a class="reference external" href="#calling-cli-commands-from-python">Calling CLI commands from Python</a></p></li>
<li><p><a class="reference external" href="#package-interface">Package Interface</a></p>
<ul>
<li><p><a class="reference external" href="#photosdb">PhotosDB</a></p></li>
<li><p><a class="reference external" href="#queryoptions">QueryOptions</a></p></li>
<li><p><a class="reference external" href="#photoinfo">PhotoInfo</a></p></li>
<li><p><a class="reference external" href="#exifinfo">ExifInfo</a></p></li>
<li><p><a class="reference external" href="#albuminfo">AlbumInfo</a></p></li>
<li><p><a class="reference external" href="#importinfo">ImportInfo</a></p></li>
<li><p><a class="reference external" href="#projectinfo">ProjectInfo</a></p></li>
<li><p><a class="reference external" href="#momentinfo">MomentInfo</a></p></li>
<li><p><a class="reference external" href="#folderinfo">FolderInfo</a></p></li>
<li><p><a class="reference external" href="#placeinfo">PlaceInfo</a></p></li>
<li><p><a class="reference external" href="#scoreinfo">ScoreInfo</a></p></li>
<li><p><a class="reference external" href="#searchinfo">SearchInfo</a></p></li>
<li><p><a class="reference external" href="#personinfo">PersonInfo</a></p></li>
<li><p><a class="reference external" href="#faceinfo">FaceInfo</a></p></li>
<li><p><a class="reference external" href="#commentinfo">CommentInfo</a></p></li>
<li><p><a class="reference external" href="#likeinfo">LikeInfo</a></p></li>
<li><p><a class="reference external" href="#adjustmentsinfo">AdjustmentsInfo</a></p></li>
<li><p><a class="reference external" href="#phototables">PhotoTables</a></p></li>
<li><p><a class="reference external" href="#raw-photos">Raw Photos</a></p></li>
<li><p><a class="reference external" href="#template-system">Template System</a></p></li>
<li><p><a class="reference external" href="#exiftool">ExifTool</a></p></li>
<li><p><a class="reference external" href="#photoexporter">PhotoExporter</a></p></li>
<li><p><a class="reference external" href="#exifwriter">ExifWriter</a></p></li>
<li><p><a class="reference external" href="#sidecarwriter">SidecarWriter</a></p></li>
<li><p><a class="reference external" href="#photosalbum">PhotosAlbum</a></p></li>
<li><p><a class="reference external" href="#textdetection">Text Detection</a></p></li>
<li><p><a class="reference external" href="#comparelibraries">Compare Libraries</a></p></li>
<li><p><a class="reference external" href="#utility-functions">Utility Functions</a></p></li>
</ul>
</li>
<li><p><a class="reference external" href="#additional-examples">Additional Examples</a></p></li>
</ul>
</section>
<section id="a-name-example-uses-of-the-python-package-example-uses-of-the-python-package-a">
<h2><span class="raw-html-m2r"><a name="example-uses-of-the-python-package">Example uses of the Python package</a></span><a class="headerlink" href="#a-name-example-uses-of-the-python-package-example-uses-of-the-python-package-a" title="Link to this heading">¶</a></h2>
<section id="print-filename-date-created-title-and-keywords-for-all-photos-in-a-library">
<h3>Print filename, date created, title, and keywords for all photos in a library<a class="headerlink" href="#print-filename-date-created-title-and-keywords-for-all-photos-in-a-library" title="Link to this heading">¶</a></h3>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;print filename, date created, title, and keywords for all photos in Photos library&quot;&quot;&quot;</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">():</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="p">,</span> <span class="n">photo</span><span class="o">.</span><span class="n">date</span><span class="p">,</span> <span class="n">photo</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="n">photo</span><span class="o">.</span><span class="n">keywords</span><span class="p">)</span>
</pre></div>
</div>
<p>The primary interface to the Photos library is the <a class="reference external" href="#photosdb">PhotosDB</a> object.  The <a class="reference external" href="#photosdb">PhotosDB</a> object provides access to the photos in the library via the <a class="reference external" href="#photosdbphotos">photos</a> method and the <a class="reference external" href="#photosdbquery">query</a>.  These methods returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects, one for each photo in the library.  The <a class="reference external" href="#photoinfo">PhotoInfo</a> object provides access to the metadata for each photo.</p>
</section>
<section id="a-name-building-simple-command-line-tools-building-simple-command-line-tools-a">
<h3><span class="raw-html-m2r"><a name="building-simple-command-line-tools">Building simple command line tools</a></span><a class="headerlink" href="#a-name-building-simple-command-line-tools-building-simple-command-line-tools-a" title="Link to this heading">¶</a></h3>
<p>osxphotos provides several useful helper functions to make it easy to build simple command line tools.  For example, the following code will print information about all photos in a library or a subset of photos filtered by one or more query options.  This mirrors the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">query</span></code> command line tool. Tools built using these helper functions can be easily distributed as a single file and run via <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">run</span> <span class="pre">script.py</span></code> so the user doesn't need to install python, any dependencies, or create a virtual environment.</p>
<p>Here's a simple example showing how to use the <code class="docutils literal notranslate"><span class="pre">query_command</span></code> decorator to implement a simple command line tool. The <code class="docutils literal notranslate"><span class="pre">query_command</span></code> decorator turns your function into a full-fledged <a class="reference external" href="https://palletsprojects.com/p/click/">Click</a> command line app that can be run via <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">run</span> <span class="pre">example.py</span></code> or <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">example.py</span></code> if you have pip installed osxphotos.  Your command will include all the query options available in <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">query</span></code> as command line options as well as <code class="docutils literal notranslate"><span class="pre">--verbose</span></code> and other convenient options.</p>
<!--[[[cog
cog.out("\n```python\n")
with open("examples/cli_example_1.py", "r") as f:
    cog.out(f.read())
cog.out("```\n")
]]]--><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Sample query command for osxphotos</span>

<span class="sd">This shows how simple it is to create a command line tool using osxphotos to process your photos.</span>

<span class="sd">Using the @query_command decorator turns your function to a full-fledged command line app that</span>
<span class="sd">can be run via `osxphotos run cli_example_1.py` or `python cli_example_1.py` if you have pip installed osxphotos.</span>

<span class="sd">Using this decorator makes it very easy to create a quick command line tool that can operate on</span>
<span class="sd">a subset of your photos. Additionally, writing a command in this way makes it easy to later</span>
<span class="sd">incorporate the command into osxphotos as a full-fledged command.</span>

<span class="sd">The decorator will add all the query options available in `osxphotos query` as command line options</span>
<span class="sd">as well as the following options:</span>
<span class="sd">--verbose</span>
<span class="sd">--timestamp</span>
<span class="sd">--theme</span>
<span class="sd">--db</span>
<span class="sd">--debug (hidden, won&#39;t show in help)</span>

<span class="sd">The decorated function will perform the query and pass the list of filtered PhotoInfo objects</span>
<span class="sd">to your function.  You can then do whatever you want with the photos.</span>

<span class="sd">For example, to run the command on only selected photos:</span>

<span class="sd">    osxphotos run cli_example_1.py --selected</span>

<span class="sd">To run the command on all photos with the keyword &quot;foo&quot;:</span>

<span class="sd">    osxphotos run cli_example_1.py --keyword foo</span>

<span class="sd">For more advanced example, see `cli_example_2.py`</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span><span class="w"> </span><span class="nn">__future__</span><span class="w"> </span><span class="kn">import</span> <span class="n">annotations</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.cli</span><span class="w"> </span><span class="kn">import</span> <span class="n">query_command</span><span class="p">,</span> <span class="n">verbose</span>


<span class="nd">@query_command</span>
<span class="k">def</span><span class="w"> </span><span class="nf">example</span><span class="p">(</span><span class="n">photos</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Sample query command for osxphotos. Prints out the filename and date of each photo.</span>

<span class="sd">    Whatever text you put in the function&#39;s docstring here, will be used as the command&#39;s</span>
<span class="sd">    help text when run via `osxphotos run cli_example_1.py --help` or `python cli_example_1.py --help`</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># verbose() will print to stdout if --verbose option is set</span>
    <span class="c1"># you can optionally provide a level (default is 1) to print only if --verbose is set to that level</span>
    <span class="c1"># for example: -VV or --verbose --verbose == level 2</span>
    <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Found </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span><span class="si">}</span><span class="s2"> photo(s)&quot;</span><span class="p">)</span>
    <span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;This message will only be printed if verbose level 2 is set&quot;</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>

    <span class="c1"># do something with photos here</span>
    <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
        <span class="c1"># photos is a list of PhotoInfo objects</span>
        <span class="c1"># see: https://rhettbull.github.io/osxphotos/reference.html#osxphotos.PhotoInfo</span>
        <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Processing </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">date</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="o">...</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="c1"># call your function here</span>
    <span class="c1"># you do not need to pass any arguments to the function</span>
    <span class="c1"># as the decorator will handle parsing the command line arguments</span>
    <span class="n">example</span><span class="p">()</span>
</pre></div>
</div>
<!--[[[end]]]--><p>Here is a more advanced example that shows how to implement a script with a &quot;dry run&quot; and &quot;resume&quot; capability that preserves state between runs. Using the built-in helpers allows you to implement complex behavior in just a few lines of code.</p>
<!--[[[cog
cog.out("\n```python\n")
with open("examples/cli_example_2.py", "r") as f:
    cog.out(f.read())
cog.out("```\n")
]]]--><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Sample query command for osxphotos</span>

<span class="sd">This shows how simple it is to create a command line tool using osxphotos to process your photos.</span>

<span class="sd">Using the @query_command decorator turns your function to a full-fledged command line app that</span>
<span class="sd">can be run via `osxphotos run cli_example_2.py` or `python cli_example_2.py` if you have pip installed osxphotos.</span>

<span class="sd">Using this decorator makes it very easy to create a quick command line tool that can operate on</span>
<span class="sd">a subset of your photos. Additionally, writing a command in this way makes it easy to later</span>
<span class="sd">incorporate the command into osxphotos as a full-fledged command.</span>

<span class="sd">The decorator will add all the query options available in `osxphotos query` as command line options</span>
<span class="sd">as well as the following options:</span>
<span class="sd">--verbose</span>
<span class="sd">--timestamp</span>
<span class="sd">--theme</span>
<span class="sd">--db</span>
<span class="sd">--debug (hidden, won&#39;t show in help)</span>

<span class="sd">The decorated function will perform the query and pass the list of filtered PhotoInfo objects</span>
<span class="sd">to your function.  You can then do whatever you want with the photos.</span>

<span class="sd">For example, to run the command on only selected photos:</span>

<span class="sd">    osxphotos run cli_example_2.py --selected</span>

<span class="sd">To run the command on all photos with the keyword &quot;foo&quot;:</span>

<span class="sd">    osxphotos run cli_example_2.py --keyword foo</span>

<span class="sd">The following helper functions may be useful and can be imported from osxphotos.cli:</span>

<span class="sd">    abort(message: str, exit_code: int = 1)</span>
<span class="sd">        Abort with error message and exit code</span>
<span class="sd">    echo(message: str)</span>
<span class="sd">        Print message to stdout using rich formatting</span>
<span class="sd">    echo_error(message: str)</span>
<span class="sd">        Print message to stderr using rich formatting</span>
<span class="sd">    logger: logging.Logger</span>
<span class="sd">        Python logger for osxphotos; for example, logger.debug(&quot;debug message&quot;)</span>
<span class="sd">    verbose(*args, level: int = 1)</span>
<span class="sd">        Print args to stdout if --verbose option is set</span>
<span class="sd">    query_command: decorator to create an osxphotos query command</span>
<span class="sd">    kvstore(name: str) -&gt; SQLiteKVStore useful for storing state between runs</span>

<span class="sd">The verbose, echo, and echo_error functions use rich formatting to print messages to stdout and stderr.</span>
<span class="sd">See https://github.com/Textualize/rich for more information on rich formatting.</span>

<span class="sd">In addition to standard rich formatting styles, the following styles will be defined</span>
<span class="sd">(and can be changed using --theme):</span>

<span class="sd">    [change]: something change</span>
<span class="sd">    [no_change]: indicate no change</span>
<span class="sd">    [count]: a count</span>
<span class="sd">    [error]: an error</span>
<span class="sd">    [filename]: a filename</span>
<span class="sd">    [filepath]: a filepath</span>
<span class="sd">    [num]: a number</span>
<span class="sd">    [time]: a time or date</span>
<span class="sd">    [tz]: a timezone</span>
<span class="sd">    [warning]: a warning</span>
<span class="sd">    [uuid]: a uuid</span>

<span class="sd">The tags should be closed with [/] to end the style.  For example:</span>

<span class="sd">    echo(&quot;[filename]foo[/] [time]bar[/]&quot;)</span>

<span class="sd">For simpler examples, see `cli_example_1.py`</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span><span class="w"> </span><span class="nn">__future__</span><span class="w"> </span><span class="kn">import</span> <span class="n">annotations</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">datetime</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">click</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.cli</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
    <span class="n">abort</span><span class="p">,</span>
    <span class="n">echo</span><span class="p">,</span>
    <span class="n">echo_error</span><span class="p">,</span>
    <span class="n">kvstore</span><span class="p">,</span>
    <span class="n">logger</span><span class="p">,</span>
    <span class="n">query_command</span><span class="p">,</span>
    <span class="n">verbose</span><span class="p">,</span>
<span class="p">)</span>


<span class="nd">@query_command</span><span class="p">()</span>
<span class="nd">@click</span><span class="o">.</span><span class="n">option</span><span class="p">(</span>
    <span class="s2">&quot;--resume&quot;</span><span class="p">,</span>
    <span class="n">is_flag</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
    <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Resume processing from last run, do not reprocess photos&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="nd">@click</span><span class="o">.</span><span class="n">option</span><span class="p">(</span>
    <span class="s2">&quot;--dry-run&quot;</span><span class="p">,</span> <span class="n">is_flag</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Do a dry run, don&#39;t actually do anything&quot;</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">example</span><span class="p">(</span><span class="n">resume</span><span class="p">,</span> <span class="n">dry_run</span><span class="p">,</span> <span class="n">photos</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Sample query command for osxphotos. Prints out the filename and date of each photo.</span>

<span class="sd">    Whatever text you put in the function&#39;s docstring here, will be used as the command&#39;s</span>
<span class="sd">    help text when run via `osxphotos run cli_example_2.py --help` or `python cli_example_2.py --help`</span>

<span class="sd">    The @query_command decorator returns a click.command so you can add additional options</span>
<span class="sd">    using standard click decorators.  For example, the --resume and --dry-run options.</span>
<span class="sd">    For more information on click, see https://palletsprojects.com/p/click/.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># abort will print the message to stderr and exit with the given exit code</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">photos</span><span class="p">:</span>
        <span class="n">abort</span><span class="p">(</span><span class="s2">&quot;Nothing to do!&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>

    <span class="c1"># verbose() will print to stdout if --verbose option is set</span>
    <span class="c1"># you can optionally provide a level (default is 1) to print only if --verbose is set to that level</span>
    <span class="c1"># for example: -VV or --verbose --verbose == level 2</span>
    <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Found [count]</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span><span class="si">}</span><span class="s2">[/] photos&quot;</span><span class="p">)</span>
    <span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;This message will only be printed if verbose level 2 is set&quot;</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>

    <span class="c1"># the logger is a python logging.Logger object</span>
    <span class="c1"># debug messages will only be printed if --debug option is set</span>
    <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">kwargs</span><span class="si">=}</span><span class="s2">&quot;</span><span class="p">)</span>

    <span class="c1"># kvstore() returns a SQLiteKVStore object for storing state between runs</span>
    <span class="c1"># this is basically a persistent dictionary that can be used to store state</span>
    <span class="c1"># see https://github.com/RhetTbull/sqlitekvstore for more information</span>
    <span class="n">kv</span> <span class="o">=</span> <span class="n">kvstore</span><span class="p">(</span><span class="s2">&quot;cli_example_2&quot;</span><span class="p">)</span>
    <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Using key-value cache: </span><span class="si">{</span><span class="n">kv</span><span class="o">.</span><span class="n">path</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>

    <span class="c1"># do something with photos here</span>
    <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
        <span class="c1"># photos is a list of PhotoInfo objects</span>
        <span class="c1"># see: https://rhettbull.github.io/osxphotos/reference.html#osxphotos.PhotoInfo</span>
        <span class="k">if</span> <span class="n">resume</span> <span class="ow">and</span> <span class="n">photo</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">in</span> <span class="n">kv</span><span class="p">:</span>
            <span class="n">echo</span><span class="p">(</span>
                <span class="sa">f</span><span class="s2">&quot;Skipping processed photo [filename]</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">[/] ([uuid]</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">[/])&quot;</span>
            <span class="p">)</span>
            <span class="k">continue</span>

        <span class="c1"># store the uuid and current time in the kvstore</span>
        <span class="c1"># the key and value must be a type supported by SQLite: int, float, str, bytes, bool, None</span>
        <span class="c1"># if you need to store other values, you should serialize them to a string or bytes first</span>
        <span class="c1"># for example, using json.dumps() or pickle.dumps()</span>
        <span class="n">kv</span><span class="p">[</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
        <span class="n">echo</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Processing [filename]</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">[/] [time]</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">date</span><span class="si">}</span><span class="s2">[/]&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">dry_run</span><span class="p">:</span>
            <span class="c1"># do something with the photo here</span>
            <span class="n">echo</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Doing something with [filename]</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">[/]&quot;</span><span class="p">)</span>

    <span class="c1"># echo_error will print to stderr</span>
    <span class="c1"># if you add [warning] or [error], it will be formatted accordingly</span>
    <span class="c1"># and include an emoji to make the message stand out</span>
    <span class="n">echo_error</span><span class="p">(</span><span class="s2">&quot;[warning]This is a warning message!&quot;</span><span class="p">)</span>
    <span class="n">echo_error</span><span class="p">(</span><span class="s2">&quot;[error]This is an error message!&quot;</span><span class="p">)</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="c1"># call your function here</span>
    <span class="c1"># you do not need to pass any arguments to the function</span>
    <span class="c1"># as the decorator will handle parsing the command line arguments</span>
    <span class="n">example</span><span class="p">()</span>
</pre></div>
</div>
<!--[[[end]]]--><p>In addition to the <code class="docutils literal notranslate"><span class="pre">query_command</span></code> decorator, you can also use the <code class="docutils literal notranslate"><span class="pre">selection_command</span></code> decorator to implement a command that operates on the current selection in Photos.</p>
<!--[[[cog
cog.out("\n```python\n")
with open("examples/cli_example_3.py", "r") as f:
    cog.out(f.read())
cog.out("```\n")
]]]--><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Sample query command for osxphotos</span>

<span class="sd">This shows how simple it is to create a command line tool using osxphotos to process your photos.</span>

<span class="sd">Using the @selection_command decorator turns your function to a full-fledged command line app that</span>
<span class="sd">can be run via `osxphotos run cli_example_1.py` or `python cli_example_1.py` if you have pip installed osxphotos.</span>

<span class="sd">Using this decorator makes it very easy to create a quick command line tool that can operate on</span>
<span class="sd">a subset of your photos. Additionally, writing a command in this way makes it easy to later</span>
<span class="sd">incorporate the command into osxphotos as a full-fledged command.</span>

<span class="sd">The decorator will add the following options to your command:</span>
<span class="sd">--verbose</span>
<span class="sd">--timestamp</span>
<span class="sd">--theme</span>
<span class="sd">--db</span>
<span class="sd">--debug (hidden, won&#39;t show in help)</span>

<span class="sd">The decorated function will get the selected photos and pass the list of PhotoInfo objects</span>
<span class="sd">to your function.  You can then do whatever you want with the photos.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span><span class="w"> </span><span class="nn">__future__</span><span class="w"> </span><span class="kn">import</span> <span class="n">annotations</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.cli</span><span class="w"> </span><span class="kn">import</span> <span class="n">selection_command</span><span class="p">,</span> <span class="n">verbose</span>


<span class="nd">@selection_command</span>
<span class="k">def</span><span class="w"> </span><span class="nf">example</span><span class="p">(</span><span class="n">photos</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Sample command for osxphotos. Prints out the filename and date of each photo</span>
<span class="sd">    currently selected in Photos.app.</span>

<span class="sd">    Whatever text you put in the function&#39;s docstring here, will be used as the command&#39;s</span>
<span class="sd">    help text when run via `osxphotos run cli_example_1.py --help` or `python cli_example_1.py --help`</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># verbose() will print to stdout if --verbose option is set</span>
    <span class="c1"># you can optionally provide a level (default is 1) to print only if --verbose is set to that level</span>
    <span class="c1"># for example: -VV or --verbose --verbose == level 2</span>
    <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Found </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span><span class="si">}</span><span class="s2"> photo(s)&quot;</span><span class="p">)</span>
    <span class="n">verbose</span><span class="p">(</span><span class="s2">&quot;This message will only be printed if verbose level 2 is set&quot;</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>

    <span class="c1"># do something with photos here</span>
    <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
        <span class="c1"># photos is a list of PhotoInfo objects</span>
        <span class="c1"># see: https://rhettbull.github.io/osxphotos/reference.html#osxphotos.PhotoInfo</span>
        <span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Processing </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">date</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
        <span class="o">...</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="c1"># call your function here</span>
    <span class="c1"># you do not need to pass any arguments to the function</span>
    <span class="c1"># as the decorator will handle parsing the command line arguments</span>
    <span class="n">example</span><span class="p">()</span>
</pre></div>
</div>
<!--[[[end]]]--></section>
</section>
<section id="a-name-concurrency-concurrency-a">
<h2><span class="raw-html-m2r"><a name="concurrency">Concurrency</a></span><a class="headerlink" href="#a-name-concurrency-concurrency-a" title="Link to this heading">¶</a></h2>
<p>OSXPhotos is not currently compatible with multiprocessing as the <code class="docutils literal notranslate"><span class="pre">PhotosDB</span></code> class cannot be pickled which required
when sharing data between processes. Photos can be exported concurrently using separate threads, however, this is
only compatible with Python 3.11 and later.  See <a class="reference external" href="https://github.com/RhetTbull/osxphotos/issues/999">issue #999</a>.
The reason for this is that internally, <code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code> uses a sqlite <code class="docutils literal notranslate"><span class="pre">ExportDB</span></code> database for managing the export,
even if you don't specify an export database. (In the case where you don't specify an export database, a temporary
in-memory database is created and then discard.) The python implementation of sqlite3 is not fully thread safe on
Python &lt; 3.11.</p>
<p>For example, the following code will work on Python &gt;= 3.11. This code is available in the <code class="docutils literal notranslate"><span class="pre">examples</span></code> directory as
<a class="reference external" href="https://github.com/RhetTbull/osxphotos/blob/main/examples/concurrent_export.py">concurrent_export.py</a>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Example for concurrent export of photos using osxphotos.PhotoExporter.export()</span>

<span class="sd">Note: concurrent export can only be used on Python 3.11 and later due to the way</span>
<span class="sd">python&#39;s sqlite3 module is implemented. See https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety</span>
<span class="sd">for more information.</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">concurrent.futures</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">time</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">click</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.cli</span><span class="w"> </span><span class="kn">import</span> <span class="n">echo</span><span class="p">,</span> <span class="n">query_command</span><span class="p">,</span> <span class="n">verbose</span>


<span class="nd">@query_command</span><span class="p">()</span>
<span class="nd">@click</span><span class="o">.</span><span class="n">option</span><span class="p">(</span>
    <span class="s2">&quot;--workers&quot;</span><span class="p">,</span>
    <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;WORKERS&quot;</span><span class="p">,</span>
    <span class="n">help</span><span class="o">=</span><span class="s2">&quot;Maximum number of worker threads to use for export. &quot;</span>
    <span class="s2">&quot;If not specified, it will default to the number of processors on the machine, multiplied by 5.&quot;</span><span class="p">,</span>
    <span class="nb">type</span><span class="o">=</span><span class="nb">int</span><span class="p">,</span>
<span class="p">)</span>
<span class="nd">@click</span><span class="o">.</span><span class="n">argument</span><span class="p">(</span>
    <span class="s2">&quot;export_dir&quot;</span><span class="p">,</span>
    <span class="nb">type</span><span class="o">=</span><span class="n">click</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">exists</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">file_okay</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">dir_okay</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">writable</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">export</span><span class="p">(</span><span class="n">workers</span><span class="p">,</span> <span class="n">export_dir</span><span class="p">,</span> <span class="n">photos</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Export photos&quot;&quot;&quot;</span>
    <span class="n">workers</span> <span class="o">=</span> <span class="n">workers</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">cpu_count</span><span class="p">()</span> <span class="o">*</span> <span class="mi">5</span>
    <span class="n">echo</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Exporting </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span><span class="si">}</span><span class="s2"> photos to </span><span class="si">{</span><span class="n">export_dir</span><span class="si">}</span><span class="s2"> using </span><span class="si">{</span><span class="n">workers</span><span class="si">}</span><span class="s2"> workers&quot;</span><span class="p">)</span>
    <span class="n">start_t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
    <span class="k">with</span> <span class="n">concurrent</span><span class="o">.</span><span class="n">futures</span><span class="o">.</span><span class="n">ThreadPoolExecutor</span><span class="p">(</span><span class="n">max_workers</span><span class="o">=</span><span class="n">workers</span><span class="p">)</span> <span class="k">as</span> <span class="n">executor</span><span class="p">:</span>
        <span class="n">futures</span> <span class="o">=</span> <span class="p">[</span>
            <span class="n">executor</span><span class="o">.</span><span class="n">submit</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">export</span><span class="p">,</span> <span class="n">export_dir</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">_</span><span class="si">{</span><span class="n">p</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
        <span class="p">]</span>
        <span class="n">exported</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">future</span> <span class="ow">in</span> <span class="n">concurrent</span><span class="o">.</span><span class="n">futures</span><span class="o">.</span><span class="n">as_completed</span><span class="p">(</span><span class="n">futures</span><span class="p">):</span>
            <span class="n">exported</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">future</span><span class="o">.</span><span class="n">result</span><span class="p">())</span>
    <span class="n">end_t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
    <span class="n">echo</span><span class="p">(</span>
        <span class="sa">f</span><span class="s2">&quot;Exported </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">exported</span><span class="p">)</span><span class="si">}</span><span class="s2"> photos to </span><span class="si">{</span><span class="n">export_dir</span><span class="si">}</span><span class="s2"> in </span><span class="si">{</span><span class="n">end_t</span><span class="o">-</span><span class="n">start_t</span><span class="si">:</span><span class="s2">.4f</span><span class="si">}</span><span class="s2"> seconds&quot;</span>
    <span class="p">)</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">export</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="a-name-calling-cli-commands-from-python-calling-cli-commands-from-python-a">
<h2><span class="raw-html-m2r"><a name="calling-cli-commands-from-python">Calling CLI commands from Python</a></span><a class="headerlink" href="#a-name-calling-cli-commands-from-python-calling-cli-commands-from-python-a" title="Link to this heading">¶</a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">osxphotos.cli</span></code> module contains the code for the <code class="docutils literal notranslate"><span class="pre">osxphotos</span></code> command line tool. If you want to call the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span></code> command from within your own code, you can do so by calling <code class="docutils literal notranslate"><span class="pre">export_cli()</span></code>:</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.cli.export</span><span class="w"> </span><span class="kn">import</span> <span class="n">export_cli</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">export_cli</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="s2">&quot;/private/tmp&quot;</span><span class="p">,</span> <span class="n">update</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">export_cli()</span></code> function takes the same arguments as the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span></code> command. See <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">help</span> <span class="pre">export</span></code> for more information. You can also reference the implementation <a class="reference external" href="https://github.com/RhetTbull/osxphotos/blob/f4574a1158e9fbd29c906196a46d57b5dd3f322b/osxphotos/cli/export.py#L1102C16-L1292">here</a>.</p>
</section>
<section id="a-name-package-interface-package-interface-a">
<h2><span class="raw-html-m2r"><a name="package-interface">Package Interface</a></span><a class="headerlink" href="#a-name-package-interface-package-interface-a" title="Link to this heading">¶</a></h2>
<section id="a-name-photosdb-photosdb-a">
<h3><span class="raw-html-m2r"><a name="photosdb">PhotosDB</a></span><a class="headerlink" href="#a-name-photosdb-photosdb-a" title="Link to this heading">¶</a></h3>
<section id="read-a-photos-library-database">
<h4>Read a Photos library database<a class="headerlink" href="#read-a-photos-library-database" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
<span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">dbfile</span><span class="o">=</span><span class="n">path</span><span class="p">)</span>
</pre></div>
</div>
<p>Reads the Photos library database and returns a PhotosDB object.</p>
<p>Pass the path to a Photos library or to a specific database file (e.g. &quot;/Users/smith/Pictures/Photos Library.photoslibrary&quot; or &quot;/Users/smith/Pictures/Photos Library.photoslibrary/database/photos.db&quot;).  Normally, it's recommended you pass the path the .photoslibrary folder, not the actual database path.  <strong>Note</strong>: In Photos, users may specify a different library to open by holding down the <em>option</em> key while opening Photos.app. See also <a class="reference external" href="#get-last-library-path">get_last_library_path</a> and <a class="reference external" href="#get-system-library-path">get_system_library_path</a></p>
<p>If an invalid path is passed, PhotosDB will raise <code class="docutils literal notranslate"><span class="pre">FileNotFoundError</span></code> exception.</p>
<p><strong>Note</strong>: If neither path or dbfile is passed, PhotosDB will use <a class="reference external" href="#get-last-library-path">get_last_library_path</a> to open the last opened Photos library.  This usually works but is not 100% reliable.  It can also lead to loading a different library than expected if the user has held down <em>option</em> key when opening Photos to switch libraries.  You may therefore want to explicitely pass the path to <code class="docutils literal notranslate"><span class="pre">PhotosDB()</span></code>.</p>
</section>
<section id="open-the-default-last-opened-photos-library">
<h4>Open the default (last opened) Photos library<a class="headerlink" href="#open-the-default-last-opened-photos-library" title="Link to this heading">¶</a></h4>
<p>The default library is the library that would open if the user opened Photos.app.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">get_last_library_path</span><span class="p">())</span>
</pre></div>
</div>
</section>
<section id="open-system-photos-library">
<h4>Open System Photos library<a class="headerlink" href="#open-system-photos-library" title="Link to this heading">¶</a></h4>
<p>In Photos 5 (Catalina / MacOS 10.15), you can use <cite>``get_system_library_path()`</cite> &lt;#get-system-library-path&gt;`_ to get the path to the System photo library if you want to ensure PhotosDB opens the system library.  This does not work on older versions of MacOS. E.g.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">path</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">get_system_library_path</span><span class="p">()</span>
<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</pre></div>
</div>
<p>also,</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">path</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">get_system_library_path</span><span class="p">()</span>
<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">dbfile</span><span class="o">=</span><span class="n">path</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="open-a-specific-photos-library">
<h4>Open a specific Photos library<a class="headerlink" href="#open-a-specific-photos-library" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="n">dbfile</span><span class="o">=</span><span class="s2">&quot;/Users/smith/Pictures/Test.photoslibrary/database/photos.db&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>or</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="s2">&quot;/Users/smith/Pictures/Test.photoslibrary&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Pass the fully qualified path to the Photos library or the actual database file inside the library. The database is called photos.db and resides in the database folder in your Photos library.  If you pass only the path to the library, PhotosDB will add the database path automatically.  The option to pass the actual database path is provided so database files can be queried even if separated from the actual .photoslibrary file.</p>
<p>Returns a PhotosDB object.</p>
<p><strong>Note</strong>: If you have a large library (e.g. many thousdands of photos), creating the PhotosDB object can take a long time (10s of seconds).  See <a class="reference external" href="#implementation-notes">Implementation Notes</a> for additional details.</p>
</section>
<section id="a-name-photosdbphotos-photos-keywords-none-uuid-none-persons-none-albums-none-images-true-movies-true-from-date-none-to-date-none-intrash-false-a">
<h4><span class="raw-html-m2r"><a name="photosdbphotos">photos(keywords=None, uuid=None, persons=None, albums=None, images=True, movies=True, from_date=None, to_date=None, intrash=False)</a></span><a class="headerlink" href="#a-name-photosdbphotos-photos-keywords-none-uuid-none-persons-none-albums-none-images-true-movies-true-from-date-none-to-date-none-intrash-false-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">([</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;keyword&#39;</span><span class="p">,]],</span> <span class="p">[</span><span class="n">uuid</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;uuid&#39;</span><span class="p">,]],</span> <span class="p">[</span><span class="n">persons</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;person&#39;</span><span class="p">,]],</span> <span class="p">[</span><span class="n">albums</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;album&#39;</span><span class="p">,]],[</span><span class="n">from_date</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">],[</span><span class="n">to_date</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">])</span>
</pre></div>
</div>
<p>Returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects.  Each PhotoInfo object represents a photo in the Photos Libary.</p>
<p>If called with no parameters, returns a list of every photo in the Photos library.</p>
<p>May be called with one or more of the following parameters to filter the list of photos returned:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span>
    <span class="n">keywords</span> <span class="o">=</span> <span class="p">[],</span>
    <span class="n">uuid</span> <span class="o">=</span> <span class="p">[],</span>
    <span class="n">persons</span> <span class="o">=</span> <span class="p">[],</span>
    <span class="n">albums</span> <span class="o">=</span> <span class="p">[],</span>
    <span class="n">images</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">,</span>
    <span class="n">movies</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">,</span>
    <span class="n">from_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">,</span>
    <span class="n">to_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">,</span>
    <span class="n">intrash</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">keywords</span></code>: list of one or more keywords.  Returns only photos containing the keyword(s).  If more than one keyword is provided finds photos matching any of the keywords (e.g. treated as &quot;or&quot;)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">uuid</span></code>: list of one or more uuids.  Returns only photos whos UUID matches.  <strong>Note</strong>: The UUID is the universally unique identifier that the Photos database uses to identify each photo.  You shouldn't normally need to use this but it is a way to access a specific photo if you know the UUID.  If more than more uuid is provided, returns photos that match any of the uuids (e.g. treated as &quot;or&quot;)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">persons</span></code>: list of one or more persons. Returns only photos containing the person(s).  If more than one person provided, returns photos that match any of the persons (e.g. treated as &quot;or&quot;)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">albums</span></code>: list of one or more album names.  Returns only photos contained in the album(s). If more than one album name is provided, returns photos contained in any of the albums (.e.g. treated as &quot;or&quot;)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">images</span></code>: bool; if True, returns photos/images; default is True</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">movies</span></code>: bool; if True, returns movies/videos; default is True</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">from_date</span></code>: datetime.datetime; if provided, finds photos where creation date &gt;= from_date; default is None</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">to_date</span></code>: datetime.datetime; if provided, finds photos where creation date &lt;= to_date; default is None</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">intrash</span></code>: if True, finds only photos in the &quot;Recently Deleted&quot; or trash folder, if False does not find any photos in the trash; default is False</p></li>
</ul>
<p>See also <a class="reference external" href="#getphoto">get_photo()</a> which is much faster for retrieving a single photo and <a class="reference external" href="#photosdbquery">query</a> which provides much more flexibility in querying the database.</p>
<p>If more than one of (keywords, uuid, persons, albums,from_date, to_date) is provided, they are treated as &quot;and&quot; criteria. E.g.</p>
<p>Finds all photos with (keyword = &quot;wedding&quot; or &quot;birthday&quot;) and (persons = &quot;Juan Rodriguez&quot;)</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">photos</span><span class="o">=</span><span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;wedding&quot;</span><span class="p">,</span><span class="s2">&quot;birthday&quot;</span><span class="p">],</span><span class="n">persons</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Juan Rodriguez&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>Find all photos tagged with keyword &quot;wedding&quot;:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;wedding&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>Find all photos of Maria Smith</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos</span><span class="o">=</span><span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">persons</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Maria Smith&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>Find all photos in album &quot;Summer Vacation&quot; or album &quot;Ski Trip&quot;</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos</span><span class="o">=</span><span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">albums</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Summer Vacation&quot;</span><span class="p">,</span> <span class="s2">&quot;Ski Trip&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>Find the single photo with uuid = &quot;osMNIO5sQFGZTbj9WrydRB&quot;</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos</span><span class="o">=</span><span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">uuid</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;osMNIO5sQFGZTbj9WrydRB&quot;</span><span class="p">])</span>
</pre></div>
</div>
<p>If you need to do more complicated searches, you can do this programmaticaly.  For example, find photos with keyword = &quot;Kids&quot; but not in album &quot;Vacation 2019&quot;</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photos1</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">albums</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Vacation 2019&quot;</span><span class="p">])</span>
<span class="n">photos2</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Kids&quot;</span><span class="p">])</span>
<span class="n">photos3</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos2</span> <span class="k">if</span> <span class="n">p</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">photos1</span><span class="p">]</span>
</pre></div>
</div>
<p>To get only movies:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">movies</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">images</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">movies</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p><strong>Note</strong> <a class="reference external" href="#photosdbphotos">PhotosDB.photos()</a> may return a different number of photos than Photos.app reports in the GUI. This is because <a class="reference external" href="#photosdbphotos">photos()</a> returns <a class="reference external" href="#hidden">hidden</a> photos, <a class="reference external" href="#shared">shared</a> photos, and for <a class="reference external" href="#burst">burst</a> photos, all selected burst images even if non-selected burst images have not been deleted. Photos only reports 1 single photo for each set of burst images until you &quot;finalize&quot; the burst by selecting key photos and deleting the others using the &quot;Make a selection&quot; option.</p>
<p>For example, in my library, Photos says I have 19,386 photos and 474 movies.  However, <a class="reference external" href="#photosdbphotos">PhotosDB.photos()</a> reports 25,002 photos.  The difference is due to 5,609 shared photos and 7 hidden photos.  (<em>Note</em> Shared photos only valid for Photos 5).  Similarly, filtering for just movies returns 625 results.  The difference between 625 and 474 reported by Photos is due to 151 shared movies.</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="s2">&quot;/Users/smith/Pictures/Photos Library.photoslibrary&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span>
<span class="go">25002</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">shared</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">shared</span><span class="p">)</span>
<span class="go">5609</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">not_shared</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">not_shared</span><span class="p">)</span>
<span class="go">19393</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">hidden</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">hidden</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">hidden</span><span class="p">)</span>
<span class="go">7</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">movies</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">movies</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">images</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">movies</span><span class="p">)</span>
<span class="go">625</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">shared_movies</span> <span class="o">=</span> <span class="p">[</span><span class="n">m</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">movies</span> <span class="k">if</span> <span class="n">m</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">shared_movies</span><span class="p">)</span>
<span class="go">151</span>
<span class="gp">&gt;&gt;&gt;</span>
</pre></div>
</div>
</section>
<section id="a-name-getphoto-get-photo-uuid-a">
<h4><span class="raw-html-m2r"><a name="getphoto">get_photo(uuid)</a></span><a class="headerlink" href="#a-name-getphoto-get-photo-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns a single PhotoInfo instance for photo with UUID matching <code class="docutils literal notranslate"><span class="pre">uuid</span></code> or None if no photo is found matching <code class="docutils literal notranslate"><span class="pre">uuid</span></code>.  If you know the UUID of a photo, <cite>``get_photo()`</cite> &lt;#getphoto&gt;`_ is much faster than <cite>``photos`</cite> &lt;#photosdbphotos&gt;`_.  See also <a class="reference external" href="#photosdbphotos">photos()</a>.</p>
</section>
<section id="a-name-photosdb-query-query-options-queryoptions-list-photoinfo-a">
<h4><span class="raw-html-m2r"><a name="photosdb-query">query(options: QueryOptions) -> List[PhotoInfo]:</a></span><a class="headerlink" href="#a-name-photosdb-query-query-options-queryoptions-list-photoinfo-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects matching the query options. This is preferred method of querying the photos database. See <a class="reference external" href="#queryoptions">QueryOptions</a> for details on the options available.</p>
</section>
<section id="a-name-photosdb-keywords-keywords-a">
<h4><span class="raw-html-m2r"><a name="photosdb-keywords">keywords</a></span><a class="headerlink" href="#a-name-photosdb-keywords-keywords-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">keywords</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">keywords</span>
</pre></div>
</div>
<p>Returns a list of the keywords found in the Photos library that are associated with at least one photo.
See also <a class="reference external" href="#keywords-as-dict">keywords_as_dict</a>.</p>
</section>
<section id="a-name-photosdb-albuminfo-album-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-albuminfo">album_info</a></span><a class="headerlink" href="#a-name-photosdb-albuminfo-album-info-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">albums</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">album_info</span>
</pre></div>
</div>
<p>Returns a list of <a class="reference external" href="#albuminfo">AlbumInfo</a> objects representing albums in the database or empty list if there are no albums.  See also <a class="reference external" href="#photosdb-albums">albums</a> and <a class="reference external" href="#photoinfo-burst-album-info">burst_album_info</a>.</p>
</section>
<section id="a-name-photosdb-albums-albums-a">
<h4><span class="raw-html-m2r"><a name="photosdb-albums">albums</a></span><a class="headerlink" href="#a-name-photosdb-albums-albums-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">album_names</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">albums</span>
</pre></div>
</div>
<p>Returns a list of the album names found in the Photos library. See also <a class="reference external" href="#photoinfo-burst-albums">burst_albums</a>.</p>
<p><strong>Note</strong>: In Photos 5.0 (MacOS 10.15/Catalina), It is possible to have more than one album with the same name in Photos.  Albums with duplicate names are treated as a single album and the photos in each are combined.  For example, if you have two albums named &quot;Wedding&quot; and each has 2 photos, osxphotos will treat this as a single album named &quot;Wedding&quot; with 4 photos in it.</p>
<p>See also <a class="reference external" href="#photosdb-albuminfo">album_info</a>.</p>
</section>
<section id="a-name-albums-shared-albums-shared-a">
<h4><span class="raw-html-m2r"><a name="albums-shared">albums_shared</a></span><a class="headerlink" href="#a-name-albums-shared-albums-shared-a" title="Link to this heading">¶</a></h4>
<p>Returns list of shared album names found in photos database (e.g. albums shared via iCloud photo sharing)</p>
<p><strong>Note</strong>: <em>Only valid for Photos 5 / MacOS 10.15</em>; on Photos &lt;= 4, prints warning and returns empty list.</p>
</section>
<section id="a-name-photosdb-import-info-import-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-import-info">import_info</a></span><a class="headerlink" href="#a-name-photosdb-import-info-import-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#importinfo">ImportInfo</a> objects representing the import sessions for the database.</p>
</section>
<section id="a-name-photosdb-project-info-project-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-project-info">project_info</a></span><a class="headerlink" href="#a-name-photosdb-project-info-project-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#projectinfo">ProjectInfo</a> objects representing the projects/creations (cards, calendars, etc.) in the database.</p>
</section>
<section id="a-name-photosdb-moment-info-moment-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-moment-info">moment_info</a></span><a class="headerlink" href="#a-name-photosdb-moment-info-moment-info-a" title="Link to this heading">¶</a></h4>
<p>Returns the  <a class="reference external" href="#momentinfo">MomentInfo</a> object for the photo or <code class="docutils literal notranslate"><span class="pre">None</span></code> if the photo does not have an associated moment.</p>
</section>
<section id="a-name-photosdb-folder-info-folder-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-folder-info">folder_info</a></span><a class="headerlink" href="#a-name-photosdb-folder-info-folder-info-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">folders</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span>
</pre></div>
</div>
<p>Returns a list of <a class="reference external" href="#folderinfo">FolderInfo</a> objects representing top level folders in the database or empty list if there are no folders.  See also <a class="reference external" href="#photosdb-folders">folders</a>.</p>
<p><strong>Note</strong>: Currently folder_info is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.</p>
</section>
<section id="a-name-photosdb-folders-folders-a">
<h4><span class="raw-html-m2r"><a name="photosdb-folders">folders</a></span><a class="headerlink" href="#a-name-photosdb-folders-folders-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">folders</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">folders</span>
</pre></div>
</div>
<p>Returns a list names of top level folder names in the database.</p>
<p><strong>Note</strong>: Currently folders is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.</p>
</section>
<section id="a-name-photosdb-persons-persons-a">
<h4><span class="raw-html-m2r"><a name="photosdb-persons">persons</a></span><a class="headerlink" href="#a-name-photosdb-persons-persons-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">persons</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">persons</span>
</pre></div>
</div>
<p>Returns a list of the person names (faces) found in the Photos library.  <strong>Note</strong>: It is of course possible to have more than one person with the same name, e.g. &quot;Maria Smith&quot;, in the database.  <code class="docutils literal notranslate"><span class="pre">persons</span></code> assumes these are the same person and will list only one person named &quot;Maria Smith&quot;.  If you need more information about persons in the database, see <a class="reference external" href="#photosdb-person_info">person_info</a>.</p>
</section>
<section id="a-name-photosdb-person-info-person-info-a">
<h4><span class="raw-html-m2r"><a name="photosdb-person-info">person_info</a></span><a class="headerlink" href="#a-name-photosdb-person-info-person-info-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">person_info</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">person_info</span>
</pre></div>
</div>
<p>Returns a list of <a class="reference external" href="#personinfo">PersonInfo</a> objects representing persons who appear in photos in the database.</p>
</section>
<section id="a-name-keywords-as-dict-keywords-as-dict-a">
<h4><span class="raw-html-m2r"><a name="keywords-as-dict">keywords_as_dict</a></span><a class="headerlink" href="#a-name-keywords-as-dict-keywords-as-dict-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">keyword_dict</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">keywords_as_dict</span>
</pre></div>
</div>
<p>Returns a dictionary of keywords found in the Photos library where key is the keyword and value is the count of how many times that keyword appears in the library (ie. how many photos are tagged with the keyword).  Resulting dictionary is in reverse sorted order (e.g. keyword with the highest count is first).</p>
</section>
<section id="a-name-keywords-without-photo-keywords-without-photo-a">
<h4><span class="raw-html-m2r"><a name="keywords-without-photo">keywords_without_photo</a></span><a class="headerlink" href="#a-name-keywords-without-photo-keywords-without-photo-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of keywords that are not associated with any photos in the library.</p>
</section>
<section id="a-name-persons-as-dict-persons-as-dict-a">
<h4><span class="raw-html-m2r"><a name="persons-as-dict">persons_as_dict</a></span><a class="headerlink" href="#a-name-persons-as-dict-persons-as-dict-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">persons_dict</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">persons_as_dict</span>
</pre></div>
</div>
<p>Returns a dictionary of persons (faces) found in the Photos library where key is the person name and value is the count of how many times that person appears in the library (ie. how many photos are tagged with the person).  Resulting dictionary is in reverse sorted order (e.g. person who appears in the most photos is listed first). <strong>Note</strong>: It is of course possible to have more than one person with the same name, e.g. &quot;Maria Smith&quot;, in the database.  <code class="docutils literal notranslate"><span class="pre">persons_as_dict</span></code> assumes these are the same person and will list only one person named &quot;Maria Smith&quot;.  If you need more information about persons in the database, see <a class="reference external" href="#photosdb-person-info">person_info</a>.</p>
</section>
<section id="a-name-albums-as-dict-albums-as-dict-a">
<h4><span class="raw-html-m2r"><a name="albums-as-dict">albums_as_dict</a></span><a class="headerlink" href="#a-name-albums-as-dict-albums-as-dict-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">albums_dict</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">albums_as_dict</span>
</pre></div>
</div>
<p>Returns a dictionary of albums found in the Photos library where key is the album name and value is the count of how many photos are in the album.  Resulting dictionary is in reverse sorted order (e.g. album with the most photos is listed first).</p>
<p><strong>Note</strong>: In Photos 5.0 (MacOS 10.15/Catalina), It is possible to have more than one album with the same name in Photos.  Albums with duplicate names are treated as a single album and the photos in each are combined.  For example, if you have two albums named &quot;Wedding&quot; and each has 2 photos, osxphotos will treat this as a single album named &quot;Wedding&quot; with 4 photos in it.</p>
</section>
<section id="a-name-albums-shared-as-dict-albums-shared-as-dict-a">
<h4><span class="raw-html-m2r"><a name="albums-shared-as-dict">albums_shared_as_dict</a></span><a class="headerlink" href="#a-name-albums-shared-as-dict-albums-shared-as-dict-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">albums_shared_dict</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">albums_shared_as_dict</span>
</pre></div>
</div>
<p>Returns a dictionary of shared albums (e.g. shared via iCloud photo sharing) found in the Photos library where key is the album name and value is the count of how many photos are in the album.  Resulting dictionary is in reverse sorted order (e.g. album with the most photos is listed first).</p>
<p><strong>Note</strong>: <em>Photos 5 / MacOS 10.15 only</em>.  On earlier versions of Photos, prints warning and returns empty dictionary.</p>
</section>
<section id="a-name-photosdb-labels-labels-a">
<h4><span class="raw-html-m2r"><a name="photosdb-labels">labels</a></span><a class="headerlink" href="#a-name-photosdb-labels-labels-a" title="Link to this heading">¶</a></h4>
<p>Returns image categorization labels associated with photos in the library as list of str.</p>
<p><strong>Note</strong>: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#photosdb-labels-normalized">labels_normalized</a>.</p>
</section>
<section id="a-name-photosdb-labels-normalized-labels-normalized-a">
<h4><span class="raw-html-m2r"><a name="photosdb-labels-normalized">labels_normalized</a></span><a class="headerlink" href="#a-name-photosdb-labels-normalized-labels-normalized-a" title="Link to this heading">¶</a></h4>
<p>Returns image categorization labels associated with photos in the library as list of str. Labels are normalized (e.g. converted to lower case).  Use of normalized strings makes it easier to search if you don't how Apple capitalizes a label.</p>
<p><strong>Note</strong>: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#photosdb-labels">labels</a>.</p>
</section>
<section id="a-name-labels-as-dict-labels-as-dict-a">
<h4><span class="raw-html-m2r"><a name="labels-as-dict">labels_as_dict</a></span><a class="headerlink" href="#a-name-labels-as-dict-labels-as-dict-a" title="Link to this heading">¶</a></h4>
<p>Returns dictionary image categorization labels associated with photos in the library where key is label and value is number of photos in the library with the label.</p>
<p><strong>Note</strong>: Only valid on Photos 5; on earlier versions, logs warning and returns empty dict. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#labels-normalized-as-dict">labels_normalized_as_dict</a>.</p>
</section>
<section id="a-name-labels-normalized-as-dict-labels-normalized-as-dict-a">
<h4><span class="raw-html-m2r"><a name="labels-normalized-as-dict">labels_normalized_as_dict</a></span><a class="headerlink" href="#a-name-labels-normalized-as-dict-labels-normalized-as-dict-a" title="Link to this heading">¶</a></h4>
<p>Returns dictionary of image categorization labels associated with photos in the library where key is normalized label and value is number of photos in the library with that label. Labels are normalized (e.g. converted to lower case).  Use of normalized strings makes it easier to search if you don't how Apple capitalizes a label.</p>
<p><strong>Note</strong>: Only valid on Photos 5; on earlier versions, logs warning and returns empty dict. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#labels-as-dict">labels_as_dict</a>.</p>
</section>
<section id="a-name-library-path-library-path-a">
<h4><span class="raw-html-m2r"><a name="library-path">library_path</a></span><a class="headerlink" href="#a-name-library-path-library-path-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photosdb</span><span class="o">.</span><span class="n">library_path</span>
</pre></div>
</div>
<p>Returns the path to the Photos library as a string</p>
</section>
<section id="a-name-db-path-db-path-a">
<h4><span class="raw-html-m2r"><a name="db-path">db_path</a></span><a class="headerlink" href="#a-name-db-path-db-path-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photosdb</span><span class="o">.</span><span class="n">db_path</span>
</pre></div>
</div>
<p>Returns the path to the Photos database PhotosDB was initialized with</p>
</section>
<section id="a-name-db-version-db-version-a">
<h4><span class="raw-html-m2r"><a name="db-version">db_version</a></span><a class="headerlink" href="#a-name-db-version-db-version-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photosdb</span><span class="o">.</span><span class="n">db_version</span>
</pre></div>
</div>
<p>Returns the version number for Photos library database.  You likely won't need this but it's provided in case needed for debugging. PhotosDB will print a warning to <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code> if you open a database version that has not been tested.</p>
</section>
<section id="a-name-photos-version-photos-version-a">
<h4><span class="raw-html-m2r"><a name="photos-version">photos_version</a></span><a class="headerlink" href="#a-name-photos-version-photos-version-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># assumes photosdb is a PhotosDB object (see above)</span>
<span class="n">photosdb</span><span class="o">.</span><span class="n">photos_version</span>
</pre></div>
</div>
<p>Returns the version number as int for version of Photos that created the library, e.g. 2, 3, 4, 5...</p>
</section>
<section id="a-name-get-db-connection-get-db-connection-a">
<h4><span class="raw-html-m2r"><a name="get-db-connection">get_db_connection()</a></span><a class="headerlink" href="#a-name-get-db-connection-get-db-connection-a" title="Link to this heading">¶</a></h4>
<p>Returns tuple of (connection, cursor) for the working copy of the Photos database.  This is useful for debugging or prototyping new features.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
<span class="n">conn</span><span class="p">,</span> <span class="n">cursor</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">get_db_connection</span><span class="p">()</span>

<span class="n">results</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
        <span class="s2">&quot;SELECT ZUUID FROM ZGENERICASSET WHERE ZFAVORITE = 1;&quot;</span>
<span class="p">)</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span>

<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
    <span class="c1"># do something</span>
    <span class="k">pass</span>

<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="a-name-executesql-execute-sql-a">
<h4><span class="raw-html-m2r"><a name="executesql">execute(sql)</a></span><a class="headerlink" href="#a-name-executesql-execute-sql-a" title="Link to this heading">¶</a></h4>
<p>Execute sql statement against the Photos database and return a sqlite cursor with the results.</p>
</section>
</section>
<section id="a-name-queryoptions-queryoptions-a">
<h3><span class="raw-html-m2r"><a name="queryoptions">QueryOptions</a></span><a class="headerlink" href="#a-name-queryoptions-queryoptions-a" title="Link to this heading">¶</a></h3>
<p>QueryOptions class for <a class="reference external" href="#photosdbquery">PhotosDB.query()</a></p>
<section id="a-name-attributes-attributes-a">
<h4><span class="raw-html-m2r"><a name="Attributes">Attributes</a></span><a class="headerlink" href="#a-name-attributes-attributes-a" title="Link to this heading">¶</a></h4>
<p>See <a class="reference external" href="https://github.com/RhetTbull/osxphotos/blob/master/osxphotos/queryoptions.py">queryoptions.py</a> for typing information.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">added_after</span></code>: search for photos added after a given date</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">added_before</span></code>: search for photos added before a given date</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">added_in_last</span></code>: search for photos added in last X datetime.timedelta</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">album</span></code>: list of album names to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">burst_photos</span></code>: include all associated burst photos for photos in query results</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">burst</span></code>: search for burst photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">cloudasset</span></code>: search for photos that are managed by iCloud</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">deleted_only</span></code>: search only for deleted photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">deleted</span></code>: also include deleted photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">description</span></code>: list of descriptions to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">duplicate</span></code>: search for duplicate photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">edited</span></code>: search for edited photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">exif</span></code>: search for photos with EXIF tags that matches the given data</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">external_edit</span></code>: search for photos edited in external apps</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">favorite</span></code>: search for favorite photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">folder</span></code>: list of folder names to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">from_date</span></code>: search for photos taken on or after this date</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">function</span></code>: list of query functions to evaluate</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">has_comment</span></code>: search for photos with comments</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">has_likes</span></code>: search for shared photos with likes</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">has_raw</span></code>: search for photos with associated raw files</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">hdr</span></code>: search for HDR photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">hidden</span></code>: search for hidden photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ignore_case</span></code>: ignore case when searching</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">in_album</span></code>: search for photos in an album</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">incloud</span></code>: search for cloud assets that are synched to iCloud</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">is_reference</span></code>: search for photos stored by reference (that is, they are not managed by Photos)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">keyword</span></code>: list of keywords to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">label</span></code>: list of labels to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">live</span></code>: search for live photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">location</span></code>: search for photos with a location</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">max_size</span></code>: maximum size of photos to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">min_size</span></code>: minimum size of photos to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">missing_bursts</span></code>: for burst photos, also include burst photos that are missing</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">missing</span></code>: search for missing photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">movies</span></code>: search for movies</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">name</span></code>: list of names to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_comment</span></code>: search for photos with no comments</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_description</span></code>: search for photos with no description</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_likes</span></code>: search for shared photos with no likes</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_location</span></code>: search for photos with no location</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_keyword</span></code>: search for photos with no keywords</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_place</span></code>: search for photos with no place</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">no_title</span></code>: search for photos with no title</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_burst</span></code>: search for non-burst photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_cloudasset</span></code>: search for photos that are not managed by iCloud</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_edited</span></code>: search for photos that have not been edited</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_favorite</span></code>: search for non-favorite photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_hdr</span></code>: search for non-HDR photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_hidden</span></code>: search for non-hidden photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_in_album</span></code>: search for photos not in an album</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_incloud</span></code>: search for cloud asset photos that are not yet synched to iCloud</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_live</span></code>: search for non-live photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_missing</span></code>: search for non-missing photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_panorama</span></code>: search for non-panorama photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_portrait</span></code>: search for non-portrait photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_reference</span></code>: search for photos not stored by reference (that is, they are managed by Photos)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_screenshot</span></code>: search for non-screenshot photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_selfie</span></code>: search for non-selfie photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_shared</span></code>: search for non-shared photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_slow_mo</span></code>: search for non-slow-mo photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">not_time_lapse</span></code>: search for non-time-lapse photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">panorama</span></code>: search for panorama photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">person</span></code>: list of person names to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">photos</span></code>: search for photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">place</span></code>: list of place names to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">portrait</span></code>: search for portrait photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">query_eval</span></code>: list of query expressions to evaluate</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">regex</span></code>: list of regular expressions to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">screenshot</span></code>: search for screenshot photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">selected</span></code>: search for selected photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">selfie</span></code>: search for selfie photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">shared</span></code>: search for shared photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">slow_mo</span></code>: search for slow-mo photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">time_lapse</span></code>: search for time-lapse photos</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">title</span></code>: list of titles to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">to_date</span></code>: search for photos taken on or before this date</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">uti</span></code>: list of UTIs to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">uuid</span></code>: list of uuids to search for</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">year</span></code>: search for photos taken in a given year</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Find all screenshots taken in 2019&quot;&quot;&quot;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
    <span class="n">results</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">osxphotos</span><span class="o">.</span><span class="n">QueryOptions</span><span class="p">(</span><span class="n">screenshot</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">year</span><span class="o">=</span><span class="p">[</span><span class="mi">2019</span><span class="p">]))</span>
    <span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="p">,</span> <span class="n">photo</span><span class="o">.</span><span class="n">date</span><span class="p">)</span>
</pre></div>
</div>
</section>
</section>
<section id="a-name-photoinfo-photoinfo-a">
<h3><span class="raw-html-m2r"><a name="photoinfo">PhotoInfo</a></span><a class="headerlink" href="#a-name-photoinfo-photoinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photosdbphotos">PhotosDB.photos()</a> returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects.  Each PhotoInfo object represents a single photo in the Photos library.</p>
<section id="a-name-photoinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-photoinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the universally unique identifier (uuid) of the photo.  This is how Photos keeps track of individual photos within the database.</p>
</section>
<section id="a-name-filename-filename-a">
<h4><span class="raw-html-m2r"><a name="filename">filename</a></span><a class="headerlink" href="#a-name-filename-filename-a" title="Link to this heading">¶</a></h4>
<p>Returns the current filename of the photo on disk.  See also <a class="reference external" href="#original-filename">original_filename</a></p>
</section>
<section id="a-name-original-filename-original-filename-a">
<h4><span class="raw-html-m2r"><a name="original-filename">original_filename</a></span><a class="headerlink" href="#a-name-original-filename-original-filename-a" title="Link to this heading">¶</a></h4>
<p>Returns the original filename of the photo when it was imported to Photos.  <strong>Note</strong>: Photos 5.0+ renames the photo when it adds the file to the library using UUID.  See also <a class="reference external" href="#filename">filename</a></p>
</section>
<section id="a-name-date-date-a">
<h4><span class="raw-html-m2r"><a name="date">date</a></span><a class="headerlink" href="#a-name-date-date-a" title="Link to this heading">¶</a></h4>
<p>Returns the create date of the photo as a timezone aware datetime.datetime object</p>
</section>
<section id="a-name-tzoffset-tzoffset-a">
<h4><span class="raw-html-m2r"><a name="tzoffset">tzoffset</a></span><a class="headerlink" href="#a-name-tzoffset-tzoffset-a" title="Link to this heading">¶</a></h4>
<p>Returns the timezone offset from UTC in seconds for the Photo creation date</p>
</section>
<section id="a-name-tzname-tzname-a">
<h4><span class="raw-html-m2r"><a name="tzname">tzname</a></span><a class="headerlink" href="#a-name-tzname-tzname-a" title="Link to this heading">¶</a></h4>
<p>Returns the timezone name for the Photos creation date</p>
</section>
<section id="a-name-date-original-date-original-a">
<h4><span class="raw-html-m2r"><a name="date-original">date_original</a></span><a class="headerlink" href="#a-name-date-original-date-original-a" title="Link to this heading">¶</a></h4>
<p>Returns the original creation date of the photo as a timezone aware datetime.datetime object.
If user changed the photo's date in Photos, this will return the original date Photos assigned
as the creation date at the time of import. The original date is stored by Photos at import time
from the date in the photo's EXIF data. If this is not set (photo had no EXIF date or photo was
imported on an older version of macOS that did not store original date) then <code class="docutils literal notranslate"><span class="pre">date_original</span></code>
returns the same value as <code class="docutils literal notranslate"><span class="pre">date</span></code>.</p>
<p>Photos 5+ only; on Photos &lt; 5.0, this will return the same value as <code class="docutils literal notranslate"><span class="pre">date</span></code>.</p>
</section>
<section id="a-name-date-added-date-added-a">
<h4><span class="raw-html-m2r"><a name="date-added">date_added</a></span><a class="headerlink" href="#a-name-date-added-date-added-a" title="Link to this heading">¶</a></h4>
<p>Returns the date the photo was added to the Photos library as a timezone aware datetime.datetime object in the local timezone, or None if the data added cannot be determined</p>
</section>
<section id="a-name-date-modified-date-modified-a">
<h4><span class="raw-html-m2r"><a name="date-modified">date_modified</a></span><a class="headerlink" href="#a-name-date-modified-date-modified-a" title="Link to this heading">¶</a></h4>
<p>Returns the modification date of the photo as a timezone aware atetime.datetime object in the local timezone or None if photo has no modification date</p>
</section>
<section id="a-name-description-description-a">
<h4><span class="raw-html-m2r"><a name="description">description</a></span><a class="headerlink" href="#a-name-description-description-a" title="Link to this heading">¶</a></h4>
<p>Returns the description of the photo</p>
</section>
<section id="a-name-title-title-a">
<h4><span class="raw-html-m2r"><a name="title">title</a></span><a class="headerlink" href="#a-name-title-title-a" title="Link to this heading">¶</a></h4>
<p>Returns the title of the photo</p>
</section>
<section id="a-name-keywords-keywords-a">
<h4><span class="raw-html-m2r"><a name="keywords">keywords</a></span><a class="headerlink" href="#a-name-keywords-keywords-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of keywords (e.g. tags) applied to the photo</p>
</section>
<section id="a-name-photoinfo-albums-albums-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-albums">albums</a></span><a class="headerlink" href="#a-name-photoinfo-albums-albums-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of albums the photo is contained in. See also <a class="reference external" href="#photoinfo-album-info">album_info</a>.</p>
</section>
<section id="a-name-photoinfo-album-info-album-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-album-info">album_info</a></span><a class="headerlink" href="#a-name-photoinfo-album-info-album-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#albuminfo">AlbumInfo</a> objects representing the albums the photo is contained in or empty list of the photo is not in any albums.  See also <a class="reference external" href="#photoinfo-albums">albums</a>.</p>
</section>
<section id="a-name-import-info-import-info-a">
<h4><span class="raw-html-m2r"><a name="import-info">import_info</a></span><a class="headerlink" href="#a-name-import-info-import-info-a" title="Link to this heading">¶</a></h4>
<p>Returns an <a class="reference external" href="#importinfo">ImportInfo</a> object representing the import session associated with the photo or <code class="docutils literal notranslate"><span class="pre">None</span></code> if there is no associated import session.</p>
</section>
<section id="a-name-project-info-project-info-a">
<h4><span class="raw-html-m2r"><a name="project-info">project_info</a></span><a class="headerlink" href="#a-name-project-info-project-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#projectinfo">ProjectInfo</a> objects representing projects/creations (cards, calendars, etc.) the photo is contained in or empty list if there are no projects associated with the photo.</p>
</section>
<section id="a-name-persons-persons-a">
<h4><span class="raw-html-m2r"><a name="persons">persons</a></span><a class="headerlink" href="#a-name-persons-persons-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of the names of the persons in the photo</p>
</section>
<section id="a-name-photoinfo-personinfo-person-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-personinfo">person_info</a></span><a class="headerlink" href="#a-name-photoinfo-personinfo-person-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#personinfo">PersonInfo</a> objects representing persons in the photo.  Each PersonInfo object is associated with one or more FaceInfo objects.</p>
</section>
<section id="a-name-photoinfo-face-info-face-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-face-info">face_info</a></span><a class="headerlink" href="#a-name-photoinfo-face-info-face-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#faceinfo">FaceInfo</a> objects representing faces in the photo.  Each face is associated with the a PersonInfo object.</p>
</section>
<section id="a-name-path-path-a">
<h4><span class="raw-html-m2r"><a name="path">path</a></span><a class="headerlink" href="#a-name-path-path-a" title="Link to this heading">¶</a></h4>
<p>Returns the absolute path to the photo on disk as a string.  <strong>Note</strong>: this returns the path to the <em>original</em> unedited file (see <a class="reference external" href="#hasadjustments">hasadjustments</a>).  If the file is missing on disk, path=<code class="docutils literal notranslate"><span class="pre">None</span></code> (see <a class="reference external" href="#ismissing">ismissing</a>).</p>
</section>
<section id="a-name-path-edited-path-edited-a">
<h4><span class="raw-html-m2r"><a name="path-edited">path_edited</a></span><a class="headerlink" href="#a-name-path-edited-path-edited-a" title="Link to this heading">¶</a></h4>
<p>Returns the absolute path to the edited photo on disk as a string.  If the photo has not been edited, returns <code class="docutils literal notranslate"><span class="pre">None</span></code>.  See also <a class="reference external" href="#path">path</a> and <a class="reference external" href="#hasadjustments">hasadjustments</a>.</p>
<p><strong>Note</strong>: will also return None if the edited photo is missing on disk.</p>
</section>
<section id="a-name-path-derivatives-path-derivatives-a">
<h4><span class="raw-html-m2r"><a name="path-derivatives">path_derivatives</a></span><a class="headerlink" href="#a-name-path-derivatives-path-derivatives-a" title="Link to this heading">¶</a></h4>
<p>Returns list of paths to any derivative preview images associated with the photo. The list of returned paths is sorted in descending order by size (the largest, presumably highest quality) preview image will be the first element in the returned list. These will be named something like this on Photos 5+:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">F19E06B8-A712-4B5C-907A-C007D37BDA16_1_101_o.jpeg</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">F19E06B8-A712-4B5C-907A-C007D37BDA16_1_102_o.jpeg</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">F19E06B8-A712-4B5C-907A-C007D37BDA16_1_105_c.jpeg</span></code></p></li>
</ul>
<p>On Photos &lt;=4, they'll be named something like:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">UNADJUSTEDNONRAW_mini_6.jpg</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">UNADJUSTEDNONRAW_thumb_6.jpg</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">Y6OofYkbR96spbS6XgwOQw_mini_1.jpg</span></code></p></li>
</ul>
<p>I've not yet decoded the suffixes to know which preview is used for which purpose but in general, if you look for the largest file, you'll get the highest resolution preview. Note that video files and Live images may have both a <code class="docutils literal notranslate"><span class="pre">.mov</span></code> video preview as well as a <code class="docutils literal notranslate"><span class="pre">.jpeg</span></code> still-image preview (the JPEG file is the one Photos displays as the &quot;cover&quot; for the video.)</p>
<p>Returns empty list if no deri images are found.</p>
</section>
<section id="a-name-path-raw-path-raw-a">
<h4><span class="raw-html-m2r"><a name="path-raw">path_raw</a></span><a class="headerlink" href="#a-name-path-raw-path-raw-a" title="Link to this heading">¶</a></h4>
<p>Returns the absolute path to the associated raw photo on disk as a string, if photo is part of a RAW+JPEG pair, otherwise returns None.  See <a class="reference external" href="#raw-photos">notes on Raw Photos</a>.</p>
</section>
<section id="a-name-has-raw-has-raw-a">
<h4><span class="raw-html-m2r"><a name="has-raw">has_raw</a></span><a class="headerlink" href="#a-name-has-raw-has-raw-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo has an associated raw image, otherwise False. (e.g. Photo is a RAW+JPEG pair). See also <a class="reference external" href="#israw">is_raw</a> and <a class="reference external" href="#raw-photos">notes on Raw Photos</a>.</p>
</section>
<section id="a-name-israw-israw-a">
<h4><span class="raw-html-m2r"><a name="israw">israw</a></span><a class="headerlink" href="#a-name-israw-israw-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a raw image. E.g. it was imported as a single raw image, not part of a RAW+JPEG pair.  See also <a class="reference external" href="#has-raw">has_raw</a> and .</p>
</section>
<section id="a-name-raw-original-raw-original-a">
<h4><span class="raw-html-m2r"><a name="raw-original">raw_original</a></span><a class="headerlink" href="#a-name-raw-original-raw-original-a" title="Link to this heading">¶</a></h4>
<p>Returns True if associated raw image and the raw image is selected in Photos via &quot;Use RAW as Original&quot;, otherwise returns False.  See <a class="reference external" href="#raw-photos">notes on Raw Photos</a>.</p>
</section>
<section id="a-name-height-height-a">
<h4><span class="raw-html-m2r"><a name="height">height</a></span><a class="headerlink" href="#a-name-height-height-a" title="Link to this heading">¶</a></h4>
<p>Returns height of the photo in pixels.  If image has been edited, returns height of the edited image, otherwise returns height of the original image.  See also <a class="reference external" href="#original-height">original_height</a>.</p>
</section>
<section id="a-name-width-width-a">
<h4><span class="raw-html-m2r"><a name="width">width</a></span><a class="headerlink" href="#a-name-width-width-a" title="Link to this heading">¶</a></h4>
<p>Returns width of the photo in pixels.  If image has been edited, returns width of the edited image, otherwise returns width of the original image.  See also <a class="reference external" href="#original-width">original_width</a>.</p>
</section>
<section id="a-name-orientation-orientation-a">
<h4><span class="raw-html-m2r"><a name="orientation">orientation</a></span><a class="headerlink" href="#a-name-orientation-orientation-a" title="Link to this heading">¶</a></h4>
<p>Returns EXIF orientation value of the photo as integer.  If image has been edited, returns orientation of the edited image, otherwise returns orientation of the original image. See also <a class="reference external" href="#original-orientation">original_orientation</a>.  If orientation cannot be determined, returns 0 (this happens if osxphotos cannot decode the adjustment info for an edited image).</p>
</section>
<section id="a-name-original-height-original-height-a">
<h4><span class="raw-html-m2r"><a name="original-height">original_height</a></span><a class="headerlink" href="#a-name-original-height-original-height-a" title="Link to this heading">¶</a></h4>
<p>Returns height of the original photo in pixels. See also <a class="reference external" href="#height">height</a>.</p>
</section>
<section id="a-name-original-width-original-width-a">
<h4><span class="raw-html-m2r"><a name="original-width">original_width</a></span><a class="headerlink" href="#a-name-original-width-original-width-a" title="Link to this heading">¶</a></h4>
<p>Returns width of the original photo in pixels. See also <a class="reference external" href="#width">width</a>.</p>
</section>
<section id="a-name-original-orientation-original-orientation-a">
<h4><span class="raw-html-m2r"><a name="original-orientation">original_orientation</a></span><a class="headerlink" href="#a-name-original-orientation-original-orientation-a" title="Link to this heading">¶</a></h4>
<p>Returns EXIF orientation value of the original photo as integer. See also <a class="reference external" href="#orientation">orientation</a>.</p>
</section>
<section id="a-name-original-filesize-original-filesize-a">
<h4><span class="raw-html-m2r"><a name="original-filesize">original_filesize</a></span><a class="headerlink" href="#a-name-original-filesize-original-filesize-a" title="Link to this heading">¶</a></h4>
<p>Returns size of the original photo in bytes as integer.</p>
</section>
<section id="a-name-ismissing-ismissing-a">
<h4><span class="raw-html-m2r"><a name="ismissing">ismissing</a></span><a class="headerlink" href="#a-name-ismissing-ismissing-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the original image file is missing on disk, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code>.  This can occur if the file has been uploaded to iCloud but not yet downloaded to the local library or if the file was deleted or imported from a disk that has been unmounted and user hasn't enabled &quot;Copy items to the Photos library&quot; in Photos preferences. <strong>Note</strong>: this status is computed based on data in the Photos library and <code class="docutils literal notranslate"><span class="pre">ismissing</span></code> does not verify if the photo is actually missing. See also <a class="reference external" href="#path">path</a>.</p>
</section>
<section id="a-name-hasadjustments-hasadjustments-a">
<h4><span class="raw-html-m2r"><a name="hasadjustments">hasadjustments</a></span><a class="headerlink" href="#a-name-hasadjustments-hasadjustments-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture has been edited, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code></p>
</section>
<section id="a-name-adjustments-adjustments-a">
<h4><span class="raw-html-m2r"><a name="adjustments">adjustments</a></span><a class="headerlink" href="#a-name-adjustments-adjustments-a" title="Link to this heading">¶</a></h4>
<p>On Photos 5+, returns an <a class="reference external" href="#adjustmentsinfo">AdjustmentsInfo</a> object representing the adjustments (edits) to the photo or None if there are no adjustments.  On earlier versions of Photos, always returns None.</p>
</section>
<section id="a-name-adjustment-type-adjustment-type-a">
<h4><span class="raw-html-m2r"><a name="adjustment_type">adjustment_type</a></span><a class="headerlink" href="#a-name-adjustment-type-adjustment-type-a" title="Link to this heading">¶</a></h4>
<p>Returns the adjustment type as an int or None. See also <a class="reference external" href="#adjustments">adjustments</a>. For photos without and adjustment this is usually 0; for photos with adjustments made by the user, this is usually 1 or 2. For photos where the phone camera made an automatic adjustment (for example, user is shooting in 16:9 aspect), this is usually 3. The value also appears to be 3 for slow-motion videos and some other media types, even if no adjustments have been made. See also <a class="reference external" href="#adjustments">adjustments</a>.</p>
</section>
<section id="a-name-external-edit-external-edit-a">
<h4><span class="raw-html-m2r"><a name="external-edit">external_edit</a></span><a class="headerlink" href="#a-name-external-edit-external-edit-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture was edited in an external editor (outside Photos.app), otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code></p>
</section>
<section id="a-name-favorite-favorite-a">
<h4><span class="raw-html-m2r"><a name="favorite">favorite</a></span><a class="headerlink" href="#a-name-favorite-favorite-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture has been marked as a favorite, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code>; for iPhoto always returns False</p>
</section>
<section id="a-name-flagged-flagged-a">
<h4><span class="raw-html-m2r"><a name="flagged">flagged</a></span><a class="headerlink" href="#a-name-flagged-flagged-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture has been marked as flagged otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code> (iPhoto only, returns False for Photos)</p>
</section>
<section id="a-name-rating-rating-a">
<h4><span class="raw-html-m2r"><a name="rating">rating</a></span><a class="headerlink" href="#a-name-rating-rating-a" title="Link to this heading">¶</a></h4>
<p>Returns star rating of photo as int from 0 to 5 (iPhoto only); for Photos, always returns 0.</p>
</section>
<section id="a-name-hidden-hidden-a">
<h4><span class="raw-html-m2r"><a name="hidden">hidden</a></span><a class="headerlink" href="#a-name-hidden-hidden-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture has been marked as hidden, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code></p>
</section>
<section id="a-name-visible-visible-a">
<h4><span class="raw-html-m2r"><a name="visible">visible</a></span><a class="headerlink" href="#a-name-visible-visible-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture is visible in library, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code>.  e.g. non-selected burst photos are not hidden but also not visible</p>
</section>
<section id="a-name-intrash-intrash-a">
<h4><span class="raw-html-m2r"><a name="intrash">intrash</a></span><a class="headerlink" href="#a-name-intrash-intrash-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the picture is in the trash ('Recently Deleted' folder), otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code></p>
</section>
<section id="a-name-date-trashed-date-trashed-a">
<h4><span class="raw-html-m2r"><a name="date-trashed">date_trashed</a></span><a class="headerlink" href="#a-name-date-trashed-date-trashed-a" title="Link to this heading">¶</a></h4>
<p>Returns the date the photo was placed in the trash as a timezone aware datetime.datetime object in the local timezone or None if photo is not in the trash</p>
</section>
<section id="a-name-location-location-a">
<h4><span class="raw-html-m2r"><a name="location">location</a></span><a class="headerlink" href="#a-name-location-location-a" title="Link to this heading">¶</a></h4>
<p>Returns latitude and longitude as a tuple of floats (latitude, longitude).  If location is not set, latitude and longitude are returned as <code class="docutils literal notranslate"><span class="pre">None</span></code></p>
</section>
<section id="a-name-latitude-latitude-a">
<h4><span class="raw-html-m2r"><a name="latitude">latitude</a></span><a class="headerlink" href="#a-name-latitude-latitude-a" title="Link to this heading">¶</a></h4>
<p>Returns latitude as a float or <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
</section>
<section id="a-name-longitude-longitude-a">
<h4><span class="raw-html-m2r"><a name="longitude">longitude</a></span><a class="headerlink" href="#a-name-longitude-longitude-a" title="Link to this heading">¶</a></h4>
<p>Returns longitude as a float or <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
</section>
<section id="a-name-place-place-a">
<h4><span class="raw-html-m2r"><a name="place">place</a></span><a class="headerlink" href="#a-name-place-place-a" title="Link to this heading">¶</a></h4>
<p>Returns a <a class="reference external" href="#placeinfo">PlaceInfo</a> object with reverse geolocation data or None if there is the photo has no reverse geolocation information.</p>
</section>
<section id="a-name-shared-shared-a">
<h4><span class="raw-html-m2r"><a name="shared">shared</a></span><a class="headerlink" href="#a-name-shared-shared-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is in a shared album, otherwise False.</p>
<p><strong>Note</strong>: <em>Only valid on Photos 5 / MacOS 10.15+; on Photos &lt;= 4, returns None.</em></p>
</section>
<section id="a-name-owner-owner-a">
<h4><span class="raw-html-m2r"><a name="owner">owner</a></span><a class="headerlink" href="#a-name-owner-owner-a" title="Link to this heading">¶</a></h4>
<p>Returns full name of the photo owner (person who shared the photo) for shared photos or None if photo is not shared. Also returns None if you are the person who shared the photo.</p>
<p><strong>Note</strong>: <em>Only valid on Photos 5 / MacOS 10.15+; on Photos &lt;= 4, returns None.</em></p>
</section>
<section id="a-name-comments-comments-a">
<h4><span class="raw-html-m2r"><a name="comments">comments</a></span><a class="headerlink" href="#a-name-comments-comments-a" title="Link to this heading">¶</a></h4>
<p>Returns list of <a class="reference external" href="#commentinfo">CommentInfo</a> objects for comments on shared photos or empty list if no comments.</p>
<p><strong>Note</strong>: <em>Only valid on Photos 5 / MacOS 10.15+; on Photos &lt;= 4, returns empty list.</em></p>
</section>
<section id="a-name-likes-likes-a">
<h4><span class="raw-html-m2r"><a name="likes">likes</a></span><a class="headerlink" href="#a-name-likes-likes-a" title="Link to this heading">¶</a></h4>
<p>Returns list of <a class="reference external" href="#likeinfo">LikeInfo</a> objects for likes on shared photos or empty list if no likes.</p>
<p><strong>Note</strong>: <em>Only valid on Photos 5 / MacOS 10.15+; on Photos &lt;= 4, returns empty list.</em></p>
</section>
<section id="a-name-isreference-isreference-a">
<h4><span class="raw-html-m2r"><a name="isreference">isreference</a></span><a class="headerlink" href="#a-name-isreference-isreference-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the original image file is a referenced file (imported without copying to the Photos library) otherwise returns <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
</section>
<section id="a-name-isphoto-isphoto-a">
<h4><span class="raw-html-m2r"><a name="isphoto">isphoto</a></span><a class="headerlink" href="#a-name-isphoto-isphoto-a" title="Link to this heading">¶</a></h4>
<p>Returns True if type is photo/still image, otherwise False</p>
</section>
<section id="a-name-ismovie-ismovie-a">
<h4><span class="raw-html-m2r"><a name="ismovie">ismovie</a></span><a class="headerlink" href="#a-name-ismovie-ismovie-a" title="Link to this heading">¶</a></h4>
<p>Returns True if type is movie/video, otherwise False</p>
</section>
<section id="a-name-iscloudasset-iscloudasset-a">
<h4><span class="raw-html-m2r"><a name="iscloudasset">iscloudasset</a></span><a class="headerlink" href="#a-name-iscloudasset-iscloudasset-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a cloud asset, that is, it is in a library synched to iCloud.  See also <a class="reference external" href="#incloud">incloud</a></p>
</section>
<section id="a-name-incloud-incloud-a">
<h4><span class="raw-html-m2r"><a name="incloud">incloud</a></span><a class="headerlink" href="#a-name-incloud-incloud-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a <a class="reference external" href="#iscloudasset">cloud asset</a> and is synched to iCloud otherwise False if photo is a cloud asset and not yet synched to iCloud. Returns None if photo is not a cloud asset.</p>
<p><strong>Note</strong>: Applies to master (original) photo only.  It's possible for the master to be in iCloud but a local edited version is not yet synched to iCloud. <code class="docutils literal notranslate"><span class="pre">incloud</span></code> provides status of only the master photo.  osxphotos does not yet provide a means to determine if the edited version is in iCloud.  If you need this feature, please open an <a class="reference external" href="https://github.com/RhetTbull/osxphotos/issues">issue</a>.</p>
</section>
<section id="a-name-syndicated-syndicated-a">
<h4><span class="raw-html-m2r"><a name="syndicated">syndicated</a></span><a class="headerlink" href="#a-name-syndicated-syndicated-a" title="Link to this heading">¶</a></h4>
<p>Return true if photo was shared via syndication (e.g. via Messages, etc.); these are photos that appear in &quot;Shared with you&quot; album. Photos 7+ only; returns None if not Photos 7+.</p>
</section>
<section id="a-name-saved-to-library-saved-to-library-a">
<h4><span class="raw-html-m2r"><a name="saved-to-library">saved_to_library</a></span><a class="headerlink" href="#a-name-saved-to-library-saved-to-library-a" title="Link to this heading">¶</a></h4>
<p>Return True if syndicated photo has been saved to library; returns False if photo is not syndicated or has not been saved to the library.
Syndicated photos are photos that appear in &quot;Shared with you&quot; album. Photos 7+ only; returns None if not Photos 7+.</p>
</section>
<section id="a-name-shared-moment-shared-moment-a">
<h4><span class="raw-html-m2r"><a name="shared-moment">shared_moment</a></span><a class="headerlink" href="#a-name-shared-moment-shared-moment-a" title="Link to this heading">¶</a></h4>
<p>Return True if photo is part of a shared moment, otherwise False.  Shared moments are created when multiple photos are shared via iCloud. (e.g. in Messages)</p>
</section>
<section id="a-name-shared-library-shared-library-a">
<h4><span class="raw-html-m2r"><a name="shared-library">shared_library</a></span><a class="headerlink" href="#a-name-shared-library-shared-library-a" title="Link to this heading">¶</a></h4>
<p>Return True if photo is included in shared iCloud library, otherwise False. Photos 8+ only; returns False if not Photos 8+.</p>
</section>
<section id="a-name-share-participant-info-share-participant-info-a">
<h4><span class="raw-html-m2r"><a name="share-participant-info">share_participant_info</a></span><a class="headerlink" href="#a-name-share-participant-info-share-participant-info-a" title="Link to this heading">¶</a></h4>
<p>Returns list of ShareParticipant objects with information on who the photo in shared iCloud library is shared with (Photos 8+ only)</p>
</section>
<section id="a-name-share-participants-share-participants-a">
<h4><span class="raw-html-m2r"><a name="share-participants">share_participants</a></span><a class="headerlink" href="#a-name-share-participants-share-participants-a" title="Link to this heading">¶</a></h4>
<p>Returns list of names of people the photo in shared iCloud library is shared with (Photos 8+ only)</p>
</section>
<section id="a-name-uti-uti-a">
<h4><span class="raw-html-m2r"><a name="uti">uti</a></span><a class="headerlink" href="#a-name-uti-uti-a" title="Link to this heading">¶</a></h4>
<p>Returns Uniform Type Identifier (UTI) for the current version of the image, for example: 'public.jpeg' or 'com.apple. quicktime-movie'.  If the image has been edited, <code class="docutils literal notranslate"><span class="pre">uti</span></code> will return the UTI for the edited image, otherwise it will return the UTI for the original image.</p>
</section>
<section id="a-name-uti-original-uti-original-a">
<h4><span class="raw-html-m2r"><a name="uti-original">uti_original</a></span><a class="headerlink" href="#a-name-uti-original-uti-original-a" title="Link to this heading">¶</a></h4>
<p>Returns Uniform Type Identifier (UTI) for the original unedited image, for example: 'public.jpeg' or 'com.apple.quicktime-movie'.</p>
</section>
<section id="a-name-uti-edited-uti-edited-a">
<h4><span class="raw-html-m2r"><a name="uti-edited">uti_edited</a></span><a class="headerlink" href="#a-name-uti-edited-uti-edited-a" title="Link to this heading">¶</a></h4>
<p>Returns Uniform Type Identifier (UTI) for the edited image, for example: 'public.jpeg'.  Returns None if the photo does not have adjustments.</p>
</section>
<section id="a-name-uti-raw-uti-raw-a">
<h4><span class="raw-html-m2r"><a name="uti-raw">uti_raw</a></span><a class="headerlink" href="#a-name-uti-raw-uti-raw-a" title="Link to this heading">¶</a></h4>
<p>Returns Uniform Type Identifier (UTI) for the associated raw image, if there is one; for example, 'com.canon.cr2-raw-image'.  If the image is raw but not part of a RAW+JPEG pair, <code class="docutils literal notranslate"><span class="pre">uti_raw</span></code> returns None.  In this case, use <code class="docutils literal notranslate"><span class="pre">uti</span></code>, or <code class="docutils literal notranslate"><span class="pre">uti_original</span></code>.  See also <a class="reference external" href="#has-raw">has_raw</a> and <a class="reference external" href="#raw-photos">notes on Raw Photos</a>.</p>
</section>
<section id="a-name-burst-burst-a">
<h4><span class="raw-html-m2r"><a name="burst">burst</a></span><a class="headerlink" href="#a-name-burst-burst-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photos is a burst image (e.g. part of a set of burst images), otherwise False.
See <a class="reference external" href="#burst-photos">burst_photos</a></p>
</section>
<section id="a-name-burst-selected-burst-selected-a">
<h4><span class="raw-html-m2r"><a name="burst-selected">burst_selected</a></span><a class="headerlink" href="#a-name-burst-selected-burst-selected-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a burst photo and has been selected from the burst set by the user, otherwise False.</p>
</section>
<section id="a-name-burst-key-burst-key-a">
<h4><span class="raw-html-m2r"><a name="burst-key">burst_key</a></span><a class="headerlink" href="#a-name-burst-key-burst-key-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a burst photo and is the key image for the burst set (the image that Photos shows on top of the burst stack), otherwise False.</p>
</section>
<section id="a-name-burst-default-pick-burst-default-pick-a">
<h4><span class="raw-html-m2r"><a name="burst-default-pick">burst_default_pick</a></span><a class="headerlink" href="#a-name-burst-default-pick-burst-default-pick-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a burst image and is the photo that Photos selected as the default image for the burst set, otherwise False.</p>
</section>
<section id="a-name-burst-photos-burst-photos-a">
<h4><span class="raw-html-m2r"><a name="burst-photos">burst_photos</a></span><a class="headerlink" href="#a-name-burst-photos-burst-photos-a" title="Link to this heading">¶</a></h4>
<p>If photo is a burst image (see <a class="reference external" href="#burst">burst</a>), returns a list of PhotoInfo objects for all other photos in the same burst set. If not a burst image, returns empty list.</p>
<p>Example below gets list of all photos that are bursts, selects one of of them and prints out the names of the other images in the burst set.  <a class="reference external" href="#photosdbphotos">PhotosDB.photos()</a> will only return the photos in the burst set that the user <a class="reference external" href="https://support.apple.com/guide/photos/view-photo-bursts-phtde06a275d/mac">selected</a> using &quot;Make a Selection...&quot; in Photos or the key image Photos selected if the user has not yet made a selection.  This is similar to how Photos displays and counts burst photos.  Using <code class="docutils literal notranslate"><span class="pre">burst_photos</span></code> you can access the other images in the burst set to export them, etc.</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="s2">&quot;/Users/smith/Pictures/Photos Library.photoslibrary&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bursts</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">burst_photo</span> <span class="o">=</span> <span class="n">bursts</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">len</span><span class="p">(</span><span class="n">burst_photo</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">)</span>
<span class="go">4</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">burst_photo</span><span class="o">.</span><span class="n">original_filename</span>
<span class="go">&#39;IMG_9851.JPG&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">burst_photo</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">IMG_9853.JPG</span>
<span class="go">IMG_9852.JPG</span>
<span class="go">IMG_9854.JPG</span>
<span class="go">IMG_9855.JPG</span>
</pre></div>
</div>
</section>
<section id="a-name-photoinfo-burst-albums-burst-albums-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-burst-albums">burst_albums</a></span><a class="headerlink" href="#a-name-photoinfo-burst-albums-burst-albums-a" title="Link to this heading">¶</a></h4>
<p>If photo is burst photo, returns list of albums it is contained in as well as any albums the key photo is contained in, otherwise returns <code class="docutils literal notranslate"><span class="pre">PhotoInfo.albums</span></code>.</p>
<p>If a burst photo which has unselected burst images (e.g. the burst images are in the library but haven't been selected by the user using the &quot;Make a selection&quot; feature) is placed in a an album, Photos treats only the selected &quot;key&quot; photo as in the album.  The unselected burst images, while associated with the photo in the album, are not technically in the album.  If you are handling one of these unselected burst photos and want to know which album it would be in based on which albums it's selected key images are in, use <code class="docutils literal notranslate"><span class="pre">burst_albums</span></code>. See also <a class="reference external" href="#photoinfo-burst-album-info">burst_album_info</a> and <a class="reference external" href="#photoinfo-albums">albums</a>.</p>
</section>
<section id="a-name-photoinfo-burst-album-info-burst-album-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-burst-album-info">burst_album_info</a></span><a class="headerlink" href="#a-name-photoinfo-burst-album-info-burst-album-info-a" title="Link to this heading">¶</a></h4>
<p>If photo is non-selected burst photo, teturns a list of <a class="reference external" href="#albuminfo">AlbumInfo</a> objects representing the albums any other photos in the same burst set are contained in.  Otherwise, returns <code class="docutils literal notranslate"><span class="pre">PhotoInfo.album_info</span></code>. See also <a class="reference external" href="#photoinfo-burst-albums">burst_albums</a> and <a class="reference external" href="#photoinfo-album-info">album_info</a>.</p>
</section>
<section id="a-name-live-photo-live-photo-a">
<h4><span class="raw-html-m2r"><a name="live-photo">live_photo</a></span><a class="headerlink" href="#a-name-live-photo-live-photo-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is an Apple live photo (ie. it has an associated &quot;live&quot; video component), otherwise returns False.  See <a class="reference external" href="#path-live-photo">path_live_photo</a>.</p>
</section>
<section id="a-name-path-live-photo-path-live-photo-a">
<h4><span class="raw-html-m2r"><a name="path-live-photo">path_live_photo</a></span><a class="headerlink" href="#a-name-path-live-photo-path-live-photo-a" title="Link to this heading">¶</a></h4>
<p>Returns the path to the live video component of a <a class="reference external" href="#live-photo">live photo</a>. If photo is not a live photo, returns None.</p>
<p><strong>Note</strong>: will also return None if the live video component is missing on disk. It's possible that the original photo may be on disk (<a class="reference external" href="#ismissing">ismissing</a>==False) but the video component is missing, likely because it has not been downloaded from iCloud.</p>
</section>
<section id="a-name-path-edited-live-photo-path-edited-live-photo-a">
<h4><span class="raw-html-m2r"><a name="path-edited-live-photo">path_edited_live_photo</a></span><a class="headerlink" href="#a-name-path-edited-live-photo-path-edited-live-photo-a" title="Link to this heading">¶</a></h4>
<p>Returns the path to the edited live video component of an edited <a class="reference external" href="#live-photo">live photo</a>. If photo is not a live photo or not edited, returns None.</p>
</section>
<section id="a-name-portrait-portrait-a">
<h4><span class="raw-html-m2r"><a name="portrait">portrait</a></span><a class="headerlink" href="#a-name-portrait-portrait-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo was taken in iPhone portrait mode, otherwise False.</p>
</section>
<section id="a-name-hdr-hdr-a">
<h4><span class="raw-html-m2r"><a name="hdr">hdr</a></span><a class="headerlink" href="#a-name-hdr-hdr-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo was taken in High Dynamic Range (HDR) mode, otherwise False.</p>
</section>
<section id="a-name-selfie-selfie-a">
<h4><span class="raw-html-m2r"><a name="selfie">selfie</a></span><a class="headerlink" href="#a-name-selfie-selfie-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a selfie (taken with front-facing camera), otherwise False.</p>
<p><strong>Note</strong>: Only implemented for Photos version 3.0+.  On Photos version &lt; 3.0, returns None.</p>
</section>
<section id="a-name-time-lapse-time-lapse-a">
<h4><span class="raw-html-m2r"><a name="time-lapse">time_lapse</a></span><a class="headerlink" href="#a-name-time-lapse-time-lapse-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a time lapse video, otherwise False.</p>
</section>
<section id="a-name-panorama-panorama-a">
<h4><span class="raw-html-m2r"><a name="panorama">panorama</a></span><a class="headerlink" href="#a-name-panorama-panorama-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a panorama, otherwise False.</p>
<p><strong>Note</strong>: The result of <code class="docutils literal notranslate"><span class="pre">PhotoInfo.panorama</span></code> will differ from the &quot;Panoramas&quot; Media Types smart album in that it will also identify panorama photos from older phones that Photos does not recognize as panoramas.</p>
</section>
<section id="a-name-slow-mo-slow-mo-a">
<h4><span class="raw-html-m2r"><a name="slow-mo">slow_mo</a></span><a class="headerlink" href="#a-name-slow-mo-slow-mo-a" title="Link to this heading">¶</a></h4>
<p>Returns True if photo is a slow motion video, otherwise False</p>
</section>
<section id="a-name-photoinfo-labels-labels-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-labels">labels</a></span><a class="headerlink" href="#a-name-photoinfo-labels-labels-a" title="Link to this heading">¶</a></h4>
<p>Returns image categorization labels associated with the photo as list of str.</p>
<p><strong>Note</strong>: Only valid on Photos 5; on earlier versions, returns empty list. In Photos 5, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#photoinfo-labels-normalized">labels_normalized</a>.</p>
</section>
<section id="a-name-photoinfo-labels-normalized-labels-normalized-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-labels-normalized">labels_normalized</a></span><a class="headerlink" href="#a-name-photoinfo-labels-normalized-labels-normalized-a" title="Link to this heading">¶</a></h4>
<p>Returns image categorization labels associated with the photo as list of str. Labels are normalized (e.g. converted to lower case).  Use of normalized strings makes it easier to search if you don't how Apple capitalizes a label. For example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
<span class="k">for</span> <span class="n">photo</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">():</span>
    <span class="k">if</span> <span class="s2">&quot;statue&quot;</span> <span class="ow">in</span> <span class="n">photo</span><span class="o">.</span><span class="n">labels_normalized</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;I found a statue! </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">original_filename</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p><strong>Note</strong>: Only valid on Photos 5+; on earlier versions, returns empty list. In Photos 5+, Photos runs machine learning image categorization against photos in the library and automatically assigns labels to photos such as &quot;People&quot;, &quot;Dog&quot;, &quot;Water&quot;, etc.  A photo may have zero or more labels associated with it.  See also <a class="reference external" href="#labels">labels</a>.</p>
</section>
<section id="a-name-photoinfo-searchinfo-search-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-searchinfo">search_info</a></span><a class="headerlink" href="#a-name-photoinfo-searchinfo-search-info-a" title="Link to this heading">¶</a></h4>
<p>Returns <a class="reference external" href="#searchinfo">SearchInfo</a> object that represents search metadata for the photo.</p>
<p><strong>Note</strong>: Only valid on Photos 5+; on ealier versions, returns None.</p>
</section>
<section id="a-name-photoinfo-search-info-normalized-search-info-normalized-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-search-info-normalized">search_info_normalized</a></span><a class="headerlink" href="#a-name-photoinfo-search-info-normalized-search-info-normalized-a" title="Link to this heading">¶</a></h4>
<p>Returns <a class="reference external" href="#searchinfo">SearchInfo</a> object that represents normalized search metadata for the photo.  This returns a SearchInfo object just as <code class="docutils literal notranslate"><span class="pre">search_info</span></code> but all the properties of the object return normalized text (converted to lowercase).</p>
<p><strong>Note</strong>: Only valid on Photos 5+; on ealier versions, returns None.</p>
</section>
<section id="a-name-photoinfo-exif-info-exif-info-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-exif-info">exif_info</a></span><a class="headerlink" href="#a-name-photoinfo-exif-info-exif-info-a" title="Link to this heading">¶</a></h4>
<p>Returns an <a class="reference external" href="#exifinfo">ExifInfo</a> object with EXIF details from the Photos database.  See <a class="reference external" href="#exifinfo">ExifInfo</a> for additional details.</p>
<p><strong>Note</strong>: Only valid on Photos 5+; on earlier versions, returns <code class="docutils literal notranslate"><span class="pre">None</span></code>.  The EXIF details returned are a subset of the actual EXIF data in a typical image.  At import Photos stores this subset in the database and it's this stored data that <code class="docutils literal notranslate"><span class="pre">exif_info</span></code> returns.</p>
<p>See also <code class="docutils literal notranslate"><span class="pre">exiftool</span></code>.</p>
</section>
<section id="a-name-photoinfo-exiftool-exiftool-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-exiftool">exiftool</a></span><a class="headerlink" href="#a-name-photoinfo-exiftool-exiftool-a" title="Link to this heading">¶</a></h4>
<p>Returns an <a class="reference external" href="#exiftool">ExifToolCaching</a> object for the photo which provides an interface to <a class="reference external" href="https://exiftool.org/">exiftool</a> allowing you to read the actual EXIF data in the image file inside the Photos library.  If <a class="reference external" href="#exifinfo">exif_info</a> doesn't give you all the data you need, you can use <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> to read the entire EXIF contents of the image.</p>
<p>If the file is missing from the library (e.g. not downloaded from iCloud), returns None.</p>
<p>exiftool must be installed in the path for this to work.  If exiftool cannot be found in the path, calling <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> will log a warning and return <code class="docutils literal notranslate"><span class="pre">None</span></code>.  You can check the exiftool path using <code class="docutils literal notranslate"><span class="pre">osxphotos.exiftool.get_exiftool_path</span></code> which will raise FileNotFoundError if exiftool cannot be found.</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">osxphotos</span><span class="o">.</span><span class="n">exiftool</span><span class="o">.</span><span class="n">get_exiftool_path</span><span class="p">()</span>
<span class="go">&#39;/usr/local/bin/exiftool&#39;</span>
<span class="gp">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">ExifToolCaching</span></code> provides the following methods:</p>
<ul class="simple">
<li><p><cite>asdict(tag_groups=True)</cite>: returns all EXIF metadata found in the file as a dictionary in following form (Note: this shows just a subset of available metadata).  See <a class="reference external" href="https://exiftool.org/">exiftool</a> documentation to understand which metadata keys are available. If <code class="docutils literal notranslate"><span class="pre">tag_groups</span></code> is True (default) dict keys are in form &quot;GROUP:TAG&quot;, e.g. &quot;IPTC:Keywords&quot;. If <code class="docutils literal notranslate"><span class="pre">tag_groups</span></code> is False, dict keys do not have group names, e.g. &quot;Keywords&quot;.</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">&#39;Composite:Aperture&#39;</span><span class="p">:</span> <span class="mf">2.2</span><span class="p">,</span>
 <span class="s1">&#39;Composite:GPSPosition&#39;</span><span class="p">:</span> <span class="s1">&#39;-34.9188916666667 138.596861111111&#39;</span><span class="p">,</span>
 <span class="s1">&#39;Composite:ImageSize&#39;</span><span class="p">:</span> <span class="s1">&#39;2754 2754&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:CreateDate&#39;</span><span class="p">:</span> <span class="s1">&#39;2017:06:20 17:18:56&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:LensMake&#39;</span><span class="p">:</span> <span class="s1">&#39;Apple&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:LensModel&#39;</span><span class="p">:</span> <span class="s1">&#39;iPhone 6s back camera 4.15mm f/2.2&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:Make&#39;</span><span class="p">:</span> <span class="s1">&#39;Apple&#39;</span><span class="p">,</span>
 <span class="s1">&#39;XMP:Title&#39;</span><span class="p">:</span> <span class="s1">&#39;Elder Park&#39;</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">json()</span></code>: returns same information as <code class="docutils literal notranslate"><span class="pre">asdict()</span></code> but as a serialized JSON string.</p></li>
</ul>
<p>The <code class="docutils literal notranslate"><span class="pre">ExifToolCaching</span></code> class caches values read from the photo via <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> and is read-only.  This speeds access to the underlying EXIF data but any changes made to the EXIF data in the image will not be reflected in subsequent calls to <code class="docutils literal notranslate"><span class="pre">exiftool</span></code>.  In practice, the images in the Photos Library should not be modified after import so this is unlikely to cause any issues.</p>
<p><strong>Caution</strong>: I caution against writing new EXIF data to photos in the Photos library because this will overwrite the original copy of the photo and could adversely affect how Photos behaves.  <code class="docutils literal notranslate"><span class="pre">exiftool.asdict()</span></code> is useful for getting access to all the photos information but if you want to write new EXIF data, I recommend you export the photo first then write the data.  <a class="reference external" href="#photoinfo-export">PhotoInfo.export()</a> does this if called with <code class="docutils literal notranslate"><span class="pre">exiftool=True</span></code>.</p>
</section>
<section id="a-name-score-score-a">
<h4><span class="raw-html-m2r"><a name="score">score</a></span><a class="headerlink" href="#a-name-score-score-a" title="Link to this heading">¶</a></h4>
<p>Returns a <a class="reference external" href="#scoreinfo">ScoreInfo</a> data class object which provides access to the computed aesthetic scores for each photo.</p>
<p><strong>Note</strong>: Valid only for Photos 5; returns None for earlier Photos versions.</p>
</section>
<section id="a-name-duplicates-duplicates-a">
<h4><span class="raw-html-m2r"><a name="duplicates">duplicates</a></span><a class="headerlink" href="#a-name-duplicates-duplicates-a" title="Link to this heading">¶</a></h4>
<p>Returns list of PhotoInfo objects for <em>possible</em> duplicates or empty list if no matching duplicates.  Photos are considered possible duplicates if the photo's original file size, date created, height, and width match another those of another photo.  This does not do a byte-for-byte comparison or compute a hash which makes it fast and allows for identification of possible duplicates even if originals are not downloaded from iCloud.  The signature-based approach should be robust enough to match duplicates created either through the &quot;duplicate photo&quot; menu item or imported twice into the library but you should not rely on this 100% for identification of all duplicates.</p>
</section>
<section id="a-name-cloud-guid-cloud-guid-a">
<h4><span class="raw-html-m2r"><a name="cloud-guid">cloud_guid</a></span><a class="headerlink" href="#a-name-cloud-guid-cloud-guid-a" title="Link to this heading">¶</a></h4>
<p>For photos in iCloud, returns the cloud GUID for the photo.  This is the unique identifier for the photo in iCloud.  For photos not in iCloud, returns None.</p>
</section>
<section id="a-name-cloud-owner-hashed-id-cloud-owner-hashed-id-a">
<h4><span class="raw-html-m2r"><a name="cloud-owner-hashed-id">cloud_owner_hashed_id</a></span><a class="headerlink" href="#a-name-cloud-owner-hashed-id-cloud-owner-hashed-id-a" title="Link to this heading">¶</a></h4>
<p>For shared photos, returns the hashed ID of the owner of the shared photo.  For photos not shared, returns None.</p>
</section>
<section id="a-name-fingerprint-fingerprint-a">
<h4><span class="raw-html-m2r"><a name="fingerprint">fingerprint</a></span><a class="headerlink" href="#a-name-fingerprint-fingerprint-a" title="Link to this heading">¶</a></h4>
<p>Returns a unique fingerprint for the original photo file.  This is a hash of the original photo file and is useful for finding duplicates or correlating photos across multiple libraries.</p>
</section>
<section id="a-name-hexdigest-hexdigest-a">
<h4><span class="raw-html-m2r"><a name="hexdigest">hexdigest</a></span><a class="headerlink" href="#a-name-hexdigest-hexdigest-a" title="Link to this heading">¶</a></h4>
<p>Returns a unique digest of the photo's properties and metadata; useful for detecting changes in any property/metadata of the photo.</p>
</section>
<section id="a-name-media-analysis-media-analysis-a">
<h4><span class="raw-html-m2r"><a name="media_analysis">media_analysis</a></span><a class="headerlink" href="#a-name-media-analysis-media-analysis-a" title="Link to this heading">¶</a></h4>
<p>Returns a dict of metadata generated by the mediaanalysisd process. This includes quality metrics and AI generated captions. Photos 5+ only.</p>
</section>
<section id="a-name-ai-caption-ai-caption-a">
<h4><span class="raw-html-m2r"><a name="ai_caption">ai_caption</a></span><a class="headerlink" href="#a-name-ai-caption-ai-caption-a" title="Link to this heading">¶</a></h4>
<p>Returns a str of the AI generated caption if one exists, otherwise empty str. The Photos media analysis process (mediaanalysisd) generates these.  Photos 5+ only.</p>
</section>
<section id="a-name-tables-tables-a">
<h4><span class="raw-html-m2r"><a name="tables">tables()</a></span><a class="headerlink" href="#a-name-tables-tables-a" title="Link to this heading">¶</a></h4>
<p>Returns a PhotoTables object which provides access to the underlying SQLite database tables for the photo.
See <a class="reference external" href="#phototables">PhotoTables</a> for more details. This is useful for debugging or developing new features but
is not intended for general use.</p>
</section>
<section id="a-name-json-json-a">
<h4><span class="raw-html-m2r"><a name="json">json()</a></span><a class="headerlink" href="#a-name-json-json-a" title="Link to this heading">¶</a></h4>
<p>Returns a JSON representation of all photo info.</p>
</section>
<section id="a-name-asdict-asdict-a">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#a-name-asdict-asdict-a" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of all photo info.</p>
</section>
<section id="a-name-photoinfo-export-export-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-export">export()</a></span><a class="headerlink" href="#a-name-photoinfo-export-export-a" title="Link to this heading">¶</a></h4>
<p><code class="docutils literal notranslate"><span class="pre">export(dest,</span> <span class="pre">filename=None,</span> <span class="pre">edited=False,</span> <span class="pre">live_photo=False,</span> <span class="pre">export_as_hardlink=False,</span> <span class="pre">overwrite=False,</span> <span class="pre">increment=True,</span> <span class="pre">sidecar_json=False,</span> <span class="pre">sidecar_exiftool=False,</span> <span class="pre">sidecar_xmp=False,</span> <span class="pre">use_photos_export=False,</span> <span class="pre">use_photokit=True,</span> <span class="pre">timeout=120,</span> <span class="pre">exiftool=False,</span> <span class="pre">use_albums_as_keywords=False,</span> <span class="pre">use_persons_as_keywords=False)</span></code></p>
<p>Export photo from the Photos library to another destination on disk.</p>
<ul class="simple">
<li><p>dest: must be valid destination path as str (or exception raised).</p></li>
<li><p>filename (optional): name of picture as str; if not provided, will use current filename.  <strong>NOTE</strong>: if provided, user must ensure file extension (suffix) is correct. For example, if photo is .CR2 file, edited image may be .jpeg.  If you provide an extension different than what the actual file is, export will print a warning but will happily export the photo using the incorrect file extension.  e.g. to get the extension of the edited photo, look at <a class="reference external" href="#path-edited">PhotoInfo.path_edited</a>.</p></li>
<li><p>edited: bool; if True (default=False), will export the edited version of the photo (or raise exception if no edited version)</p></li>
<li><p>export_as_hardlink: bool; if True (default=False), will hardlink files instead of copying them</p></li>
<li><p>overwrite: bool; if True (default=False), will overwrite files if they alreay exist</p></li>
<li><p>live_photo: bool; if True (default=False), will also export the associted .mov for live photos; exported live photo will be named filename.mov</p></li>
<li><p>increment: bool; if True (default=True), will increment file name until a non-existent name is found</p></li>
<li><p>sidecar_json: (bool, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name</p></li>
<li><p>sidecar_json: (bool, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name; resulting json file will include tag group names (e.g. <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-G</span> <span class="pre">-j</span></code>)</p></li>
<li><p>sidecar_exiftool: (bool, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name; resulting json file will not include tag group names (e.g. <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-j</span></code>)</p></li>
<li><p>sidecar_xmp: (bool, default = False); if True will also write a XMP sidecar with metadata; sidecar filename will be dest/filename.xmp where filename is the stem of the photo name</p></li>
<li><p>use_photos_export: (bool, default=False); if True will attempt to export photo via AppleScript or PhotoKit interaction with Photos</p></li>
<li><p>use_photokit: (bool, default=True); if True will attempt to export photo via photokit instead of AppleScript when used with use_photos_export</p></li>
<li><p>timeout: (int, default=120) timeout in seconds used with use_photos_export</p></li>
<li><p>exiftool: (bool, default = False) if True, will use <a class="reference external" href="https://exiftool.org/">exiftool</a> to write metadata directly to the exported photo; exiftool must be installed and in the system path</p></li>
<li><p>use_albums_as_keywords: (bool, default = False); if True, will use album names as keywords when exporting metadata with exiftool or sidecar</p></li>
<li><p>use_persons_as_keywords: (bool, default = False); if True, will use person names as keywords when exporting metadata with exiftool or sidecar</p></li>
</ul>
<p>Returns: list of paths to exported files. More than one file could be exported, for example if live_photo=True, both the original image and the associated .mov file will be exported</p>
<p>The json sidecar file can be used by exiftool to apply the metadata from the json file to the image.  For example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="s2">&quot;/Users/smith/Pictures/Photos Library.photoslibrary&quot;</span><span class="p">)</span>
<span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
<span class="n">photos</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">export</span><span class="p">(</span><span class="s2">&quot;/tmp&quot;</span><span class="p">,</span><span class="s2">&quot;photo_name.jpg&quot;</span><span class="p">,</span><span class="n">sidecar_json</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Then</p>
<p><code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-j=photo_name.json</span> <span class="pre">photo_name.jpg</span></code></p>
<p>If overwrite=False and increment=False, export will fail if destination file already exists</p>
</section>
<section id="a-name-rendertemplate-render-template-template-str-options-none-a">
<h4><span class="raw-html-m2r"><a name="rendertemplate">render_template(template_str, options=None)</a></span><a class="headerlink" href="#a-name-rendertemplate-render-template-template-str-options-none-a" title="Link to this heading">¶</a></h4>
<p>Render template string for photo.  none_str is used if template substitution results in None value and no default specified.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">template_str</span></code>: str in metadata template language (MTL) format. See also <a class="reference external" href="#template-system">Template System</a> table. See notes below regarding specific details of the syntax.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">options</span></code>: an optional osxphotos.phototemplate.RenderOptions object specifying the options to pass to the rendering engine.</p></li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">RenderOptions</span></code> has the following properties:</p>
<ul class="simple">
<li><p>template: str template</p></li>
<li><p>none<em>str: str to use default for None values, default is '</em>'</p></li>
<li><p>path_sep: optional string to use as path separator, default is os.path.sep</p></li>
<li><p>expand_inplace: expand multi-valued substitutions in-place as a single string instead of returning individual strings</p></li>
<li><p>inplace_sep: optional string to use as separator between multi-valued keywords with expand_inplace; default is ','</p></li>
<li><p>filename: if True, template output will be sanitized to produce valid file name</p></li>
<li><p>dirname: if True, template output will be sanitized to produce valid directory name</p></li>
<li><p>strip: if True, strips leading/trailing whitespace from rendered templates</p></li>
<li><p>edited_version: set to True if you want {edited_version} to resolve to True (e.g. exporting edited version of photo)</p></li>
<li><p>export_dir: set to the export directory if you want to evalute {export_dir} template</p></li>
<li><p>filepath: set to value for filepath of the exported photo if you want to evaluate {filepath} template</p></li>
<li><p>quote: quote path templates for execution in the shell</p></li>
</ul>
<p>Returns a tuple of (rendered, unmatched) where rendered is a list of rendered strings with all substitutions made and unmatched is a list of any strings that resembled a template substitution but did not match a known substitution. E.g. if template contained &quot;{foo}&quot;, unmatched would be [&quot;foo&quot;].  If there are unmatched strings, rendered will be [].  E.g. a template statement must fully match or will result in error and return all unmatched fields in unmatched.</p>
<p>e.g. <code class="docutils literal notranslate"><span class="pre">photo.render_template(&quot;{created.year}/{foo}&quot;)</span></code> would return <code class="docutils literal notranslate"><span class="pre">([],[&quot;foo&quot;])</span></code></p>
<p>Some substitutions, notably <code class="docutils literal notranslate"><span class="pre">album</span></code>, <code class="docutils literal notranslate"><span class="pre">keyword</span></code>, and <code class="docutils literal notranslate"><span class="pre">person</span></code> could return multiple values, hence a new string will be return for each possible substitution (hence why a list of rendered strings is returned).  For example, a photo in 2 albums: 'Vacation' and 'Family' would result in the following rendered values if template was &quot;{created.year}/{album}&quot; and created.year == 2020: <code class="docutils literal notranslate"><span class="pre">[&quot;2020/Vacation&quot;,&quot;2020/Family&quot;]</span></code></p>
<p>See <a class="reference external" href="#template-system">Template System</a> for additional details.</p>
</section>
<section id="a-name-photoinfo-detected-text-detected-text-confidence-threshold-text-detection-confidence-threshold-a">
<h4><span class="raw-html-m2r"><a name="photoinfo-detected-text">detected_text(confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD)</a></span><a class="headerlink" href="#a-name-photoinfo-detected-text-detected-text-confidence-threshold-text-detection-confidence-threshold-a" title="Link to this heading">¶</a></h4>
<p>Detects text in photo and returns lists of results as (detected text, confidence)</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">confidence_threshold</span></code>: float between 0.0 and 1.0. If text detection confidence is below this threshold, text will not be returned. Default is <code class="docutils literal notranslate"><span class="pre">osxphotos._constants.TEXT_DETECTION_CONFIDENCE_THRESHOLD</span></code></p></li>
</ul>
<p>If photo is edited, uses the edited photo, otherwise the original; falls back to the preview image if neither edited or original is available.</p>
<p>Returns: list of (detected text, confidence) tuples.</p>
<p>Note: This is <em>not</em> the same as Live Text in macOS Monterey.  When using <code class="docutils literal notranslate"><span class="pre">detected_text()</span></code>, osxphotos will use Apple's <a class="reference external" href="https://developer.apple.com/documentation/vision/recognizing_text_in_images?language=objc">Vision framework</a> to perform text detection on the image.  On my circa 2013 MacBook Pro, this takes about 2 seconds per image.  <code class="docutils literal notranslate"><span class="pre">detected_text()</span></code> does memoize the results for a given <code class="docutils literal notranslate"><span class="pre">confidence_threshold</span></code> so repeated calls will not re-process the photo.  This works only on macOS Catalina (10.15) or later.</p>
<p>See also <a class="reference external" href="#textdetection">Text Detection</a>.</p>
</section>
</section>
<section id="a-name-exifinfo-exifinfo-a">
<h3><span class="raw-html-m2r"><a name="exifinfo">ExifInfo</a></span><a class="headerlink" href="#a-name-exifinfo-exifinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photoinfo-exif-info">PhotosInfo.exif_info</a> returns an <code class="docutils literal notranslate"><span class="pre">ExifInfo</span></code> object with some EXIF data about the photo (Photos 5 only).  <code class="docutils literal notranslate"><span class="pre">ExifInfo</span></code> contains the following properties:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">flash_fired</span><span class="p">:</span> <span class="nb">bool</span>
<span class="n">iso</span><span class="p">:</span> <span class="nb">int</span>
<span class="n">metering_mode</span><span class="p">:</span> <span class="nb">int</span>
<span class="n">sample_rate</span><span class="p">:</span> <span class="nb">int</span>
<span class="n">track_format</span><span class="p">:</span> <span class="nb">int</span>
<span class="n">white_balance</span><span class="p">:</span> <span class="nb">int</span>
<span class="n">aperture</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">bit_rate</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">duration</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">exposure_bias</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">focal_length</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">fps</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">latitude</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">longitude</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">shutter_speed</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">camera_make</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">camera_model</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">codec</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">lens_model</span><span class="p">:</span> <span class="nb">str</span>
<span class="n">date</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span> <span class="o">|</span> <span class="kc">None</span>
<span class="n">tzoffset</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span>
<span class="n">tzname</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span>
</pre></div>
</div>
<p>For example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="n">nikon_photos</span> <span class="o">=</span> <span class="p">[</span>
    <span class="n">p</span>
    <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
    <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">camera_make</span> <span class="ow">and</span> <span class="s2">&quot;nikon&quot;</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">camera_make</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="p">]</span>
</pre></div>
</div>
</section>
<section id="a-name-albuminfo-albuminfo-a">
<h3><span class="raw-html-m2r"><a name="albuminfo">AlbumInfo</a></span><a class="headerlink" href="#a-name-albuminfo-albuminfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photosdb-albuminfo">PhotosDB.album_info</a> and <a class="reference external" href="#photoinfo-album-info">PhotoInfo.album_info</a> return a list of AlbumInfo objects.  Each AlbumInfo object represents a single album in the Photos library.</p>
<section id="a-name-albuminfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="albuminfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-albuminfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the universally unique identifier (uuid) of the album.  This is how Photos keeps track of individual objects within the database.</p>
</section>
<section id="id63">
<h4><span class="raw-html-m2r"><a name="title">title</a></span><a class="headerlink" href="#id63" title="Link to this heading">¶</a></h4>
<p>Returns the title or name of the album.</p>
</section>
<section id="a-name-albumphotos-photos-a">
<h4><span class="raw-html-m2r"><a name="albumphotos">photos</a></span><a class="headerlink" href="#a-name-albumphotos-photos-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects representing each photo contained in the album sorted in the same order as in Photos. (e.g. if photos were manually sorted in the Photos albums, photos returned by <code class="docutils literal notranslate"><span class="pre">photos</span></code> will be in same order as they appear in the Photos album)</p>
</section>
<section id="a-name-creation-date-creation-date-a">
<h4><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span><a class="headerlink" href="#a-name-creation-date-creation-date-a" title="Link to this heading">¶</a></h4>
<p>Returns the creation date as a timezone aware datetime.datetime object of the album.</p>
</section>
<section id="a-name-start-date-start-date-a">
<h4><span class="raw-html-m2r"><a name="start-date">start_date</a></span><a class="headerlink" href="#a-name-start-date-start-date-a" title="Link to this heading">¶</a></h4>
<p>Returns the date of earliest photo in the album as a timezone aware datetime.datetime object.</p>
</section>
<section id="a-name-end-date-end-date-a">
<h4><span class="raw-html-m2r"><a name="end-date">end_date</a></span><a class="headerlink" href="#a-name-end-date-end-date-a" title="Link to this heading">¶</a></h4>
<p>Returns the date of latest photo in the album as a timezone aware datetime.datetime object.</p>
</section>
<section id="a-name-folder-list-folder-list-a">
<h4><span class="raw-html-m2r"><a name="folder-list">folder_list</a></span><a class="headerlink" href="#a-name-folder-list-folder-list-a" title="Link to this heading">¶</a></h4>
<p>Returns a hierarchical list of <a class="reference external" href="#folderinfo">FolderInfo</a> objects representing the folders the album is contained in.  For example, if album &quot;AlbumInFolder&quot; is in SubFolder2 of Folder1 as illustrated below, would return a list of <code class="docutils literal notranslate"><span class="pre">FolderInfo</span></code> objects representing [&quot;Folder1&quot;, &quot;SubFolder2&quot;]</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Photos Library
├── Folder1
    ├── SubFolder1
    ├── SubFolder2
        └── AlbumInFolder
</pre></div>
</div>
</section>
<section id="a-name-folder-names-folder-names-a">
<h4><span class="raw-html-m2r"><a name="folder-names">folder_names</a></span><a class="headerlink" href="#a-name-folder-names-folder-names-a" title="Link to this heading">¶</a></h4>
<p>Returns a hierarchical list of names of the folders the album is contained in.  For example, if album is in SubFolder2 of Folder1 as illustrated below, would return [&quot;Folder1&quot;, &quot;SubFolder2&quot;].</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Photos Library
├── Folder1
    ├── SubFolder1
    ├── SubFolder2
        └── AlbumInFolder
</pre></div>
</div>
</section>
<section id="a-name-parent-parent-a">
<h4><span class="raw-html-m2r"><a name="parent">parent</a></span><a class="headerlink" href="#a-name-parent-parent-a" title="Link to this heading">¶</a></h4>
<p>Returns a <a class="reference external" href="#folderinfo">FolderInfo</a> object representing the albums parent folder or <code class="docutils literal notranslate"><span class="pre">None</span></code> if album is not a in a folder.</p>
</section>
<section id="id67">
<h4><span class="raw-html-m2r"><a name="owner">owner</a></span><a class="headerlink" href="#id67" title="Link to this heading">¶</a></h4>
<p>Returns full name of the album owner (person who shared the album) for shared albums or None if album is not shared.</p>
<p><strong>Note</strong>: <em>Only valid on Photos 5 / MacOS 10.15+; on Photos &lt;= 4, returns None.</em>Only valid on Photos 5 / MacOS 10.15*</p>
</section>
<section id="id68">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id68" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the AlbumInfo object.</p>
</section>
</section>
<section id="a-name-importinfo-importinfo-a">
<h3><span class="raw-html-m2r"><a name="importinfo">ImportInfo</a></span><a class="headerlink" href="#a-name-importinfo-importinfo-a" title="Link to this heading">¶</a></h3>
<p>PhotosDB.import_info returns a list of ImportInfo objects.  Each ImportInfo object represents an import session in the library.  PhotoInfo.import_info returns a single ImportInfo object representing the import session for the photo (or <code class="docutils literal notranslate"><span class="pre">None</span></code> if no associated import session).</p>
<section id="a-name-importinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="importinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-importinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the universally unique identifier (uuid) of the import session.  This is how Photos keeps track of individual objects within the database.</p>
</section>
<section id="a-name-importphotos-photos-a">
<h4><span class="raw-html-m2r"><a name="importphotos">photos</a></span><a class="headerlink" href="#a-name-importphotos-photos-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects representing each photo contained in the import session.</p>
</section>
<section id="id70">
<h4><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span><a class="headerlink" href="#id70" title="Link to this heading">¶</a></h4>
<p>Returns the creation date as a timezone aware datetime.datetime object of the import session.</p>
</section>
<section id="id71">
<h4><span class="raw-html-m2r"><a name="start-date">start_date</a></span><a class="headerlink" href="#id71" title="Link to this heading">¶</a></h4>
<p>Returns the start date as a timezone aware datetime.datetime object for when the import session began.</p>
</section>
<section id="id72">
<h4><span class="raw-html-m2r"><a name="end-date">end_date</a></span><a class="headerlink" href="#id72" title="Link to this heading">¶</a></h4>
<p>Returns the end date as a timezone aware datetime.datetime object for when the import session completed.</p>
<p><strong>Note</strong>: On Photos &lt;=4, <code class="docutils literal notranslate"><span class="pre">start_date</span></code> and <code class="docutils literal notranslate"><span class="pre">end_date</span></code> will be the same as <code class="docutils literal notranslate"><span class="pre">creation_date</span></code>.</p>
</section>
<section id="id73">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id73" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the import session.</p>
</section>
</section>
<section id="a-name-projectinfo-projectinfo-a">
<h3><span class="raw-html-m2r"><a name="projectinfo">ProjectInfo</a></span><a class="headerlink" href="#a-name-projectinfo-projectinfo-a" title="Link to this heading">¶</a></h3>
<p>PhotosDB.projcet_info returns a list of ProjectInfo objects.  Each ProjectInfo object represents a project in the library.  PhotoInfo.project_info returns a list of ProjectInfo objects for each project the photo is contained in.</p>
<p>Projects (found under &quot;My Projects&quot; in Photos) are projects or creations such as cards, calendars, and slideshows created in Photos.  osxphotos provides only very basic information about projects and projects created with third party plugins may not accessible to osxphotos.</p>
<section id="a-name-projectinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="projectinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-projectinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the universally unique identifier (uuid) of the project.  This is how Photos keeps track of individual objects within the database.</p>
</section>
<section id="id74">
<h4><span class="raw-html-m2r"><a name="title">title</a></span><a class="headerlink" href="#id74" title="Link to this heading">¶</a></h4>
<p>Returns the title or name of the project.</p>
</section>
<section id="a-name-projectphotos-photos-a">
<h4><span class="raw-html-m2r"><a name="projectphotos">photos</a></span><a class="headerlink" href="#a-name-projectphotos-photos-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#photoinfo">PhotoInfo</a> objects representing each photo contained in the project.</p>
</section>
<section id="id76">
<h4><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span><a class="headerlink" href="#id76" title="Link to this heading">¶</a></h4>
<p>Returns the creation date as a timezone aware datetime.datetime object of the project.</p>
</section>
<section id="id77">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id77" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the ProjectInfo object.</p>
</section>
</section>
<section id="a-name-momentinfo-momentinfo-a">
<h3><span class="raw-html-m2r"><a name="momentinfo">MomentInfo</a></span><a class="headerlink" href="#a-name-momentinfo-momentinfo-a" title="Link to this heading">¶</a></h3>
<p>PhotoInfo.moment_info return the MomentInfo object for the photo.  The MomentInfo object contains information about the photo's moment as assigned by Photos.  The MomentInfo object contains the following properties:</p>
<section id="a-name-pk-pk-a">
<h4><span class="raw-html-m2r"><a name="pk">pk</a></span><a class="headerlink" href="#a-name-pk-pk-a" title="Link to this heading">¶</a></h4>
<p>Returns the primary key of the moment in the Photos database.</p>
</section>
<section id="id78">
<h4><span class="raw-html-m2r"><a name="location">location</a></span><a class="headerlink" href="#id78" title="Link to this heading">¶</a></h4>
<p>Returns the location of the moment as a tuple of (latitude, longitude).</p>
</section>
<section id="id79">
<h4><span class="raw-html-m2r"><a name="title">title</a></span><a class="headerlink" href="#id79" title="Link to this heading">¶</a></h4>
<p>Returns the title of the moment.</p>
</section>
<section id="a-name-subtitle-subtitle-a">
<h4><span class="raw-html-m2r"><a name="subtitle">subtitle</a></span><a class="headerlink" href="#a-name-subtitle-subtitle-a" title="Link to this heading">¶</a></h4>
<p>Returns the subtitle of the moment.</p>
</section>
<section id="id80">
<h4><span class="raw-html-m2r"><a name="start-date">start_date</a></span><a class="headerlink" href="#id80" title="Link to this heading">¶</a></h4>
<p>Returns the start date of the moment as a timezone aware datetime.datetime object.</p>
</section>
<section id="id81">
<h4><span class="raw-html-m2r"><a name="end-date">end_date</a></span><a class="headerlink" href="#id81" title="Link to this heading">¶</a></h4>
<p>Returns the end date of the moment as a timezone aware datetime.datetime object.</p>
</section>
<section id="id82">
<h4><span class="raw-html-m2r"><a name="date">date</a></span><a class="headerlink" href="#id82" title="Link to this heading">¶</a></h4>
<p>Returns the date of the moment as a timezone aware datetime.datetime object.</p>
</section>
<section id="a-name-modification-date-modification-date-a">
<h4><span class="raw-html-m2r"><a name="modification-date">modification_date</a></span><a class="headerlink" href="#a-name-modification-date-modification-date-a" title="Link to this heading">¶</a></h4>
<p>Returns the modification date of the moment as a timezone aware datetime.datetime object.</p>
</section>
<section id="a-name-photos-photos-a">
<h4><span class="raw-html-m2r"><a name="photos">photos</a></span><a class="headerlink" href="#a-name-photos-photos-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of [PhotoInfo] objects representing the photos in the moment.</p>
</section>
<section id="id83">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id83" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the moment.</p>
</section>
</section>
<section id="a-name-folderinfo-folderinfo-a">
<h3><span class="raw-html-m2r"><a name="folderinfo">FolderInfo</a></span><a class="headerlink" href="#a-name-folderinfo-folderinfo-a" title="Link to this heading">¶</a></h3>
<p>PhotosDB.folder_info returns a list of FolderInfo objects representing the top level folders in the library.  Each FolderInfo object represents a single folder in the Photos library.</p>
<section id="a-name-folderinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="folderinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-folderinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the universally unique identifier (uuid) of the folder.  This is how Photos keeps track of individual objects within the database.</p>
</section>
<section id="id84">
<h4><span class="raw-html-m2r"><a name="title">title</a></span><a class="headerlink" href="#id84" title="Link to this heading">¶</a></h4>
<p>Returns the title or name of the folder.</p>
</section>
<section id="a-name-folderinfo-album-info-album-info-a">
<h4><span class="raw-html-m2r"><a name="folderinfo-album-info">album_info</a></span><a class="headerlink" href="#a-name-folderinfo-album-info-album-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#albuminfo">AlbumInfo</a> objects representing each album contained in the folder.</p>
</section>
<section id="a-name-folderinfo-album-info-shared-album-info-shared-a">
<h4><span class="raw-html-m2r"><a name="folderinfo-album-info-shared">album_info_shared</a></span><a class="headerlink" href="#a-name-folderinfo-album-info-shared-album-info-shared-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#albuminfo">AlbumInfo</a> objects for each shared album in the photos database.</p>
<p><strong>Note</strong>: Only valid for Photos 5+; on Photos &lt;= 4, prints warning and returns empty list.</p>
</section>
<section id="a-name-subfolders-subfolders-a">
<h4><span class="raw-html-m2r"><a name="subfolders">subfolders</a></span><a class="headerlink" href="#a-name-subfolders-subfolders-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#folderinfo">FolderInfo</a> objects representing the sub-folders of the folder.</p>
</section>
<section id="id88">
<h4><span class="raw-html-m2r"><a name="parent">parent</a></span><a class="headerlink" href="#id88" title="Link to this heading">¶</a></h4>
<p>Returns a <a class="reference external" href="#folderinfo">FolderInfo</a> object representing the folder's parent folder or <code class="docutils literal notranslate"><span class="pre">None</span></code> if album is not a in a folder.</p>
</section>
<section id="a-name-sort-order-sort-order-a">
<h4><span class="raw-html-m2r"><a name="sort-order">sort_order</a></span><a class="headerlink" href="#a-name-sort-order-sort-order-a" title="Link to this heading">¶</a></h4>
<p>Returns album sort order (as <code class="docutils literal notranslate"><span class="pre">AlbumSortOrder</span></code> enum).  On Photos &lt;=4, always returns <code class="docutils literal notranslate"><span class="pre">AlbumSortOrder.MANUAL</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">AlbumSortOrder</span></code> has following values:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">UNKNOWN</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">MANUAL</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">NEWEST_FIRST</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">OLDEST_FIRST</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">TITLE</span></code></p></li>
</ul>
</section>
<section id="a-name-photo-indexphoto-photo-index-photo-a">
<h4><span class="raw-html-m2r"><a name="photo-indexphoto">photo_index(photo)</a></span><a class="headerlink" href="#a-name-photo-indexphoto-photo-index-photo-a" title="Link to this heading">¶</a></h4>
<p>Returns index of photo in album (based on album sort order).</p>
</section>
<section id="id90">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id90" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the FolderInfo object.</p>
<p><strong>Note</strong>: FolderInfo and AlbumInfo objects effectively work as a linked list.  The children of a folder are contained in <code class="docutils literal notranslate"><span class="pre">subfolders</span></code> and <code class="docutils literal notranslate"><span class="pre">album_info</span></code> and the parent object of both <code class="docutils literal notranslate"><span class="pre">AlbumInfo</span></code> and <code class="docutils literal notranslate"><span class="pre">FolderInfo</span></code> is represented by <code class="docutils literal notranslate"><span class="pre">parent</span></code>.  For example:</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span>
<span class="go">[&lt;osxphotos.albuminfo.FolderInfo object at 0x10fcc0160&gt;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">title</span>
<span class="go">&#39;Folder1&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">subfolders</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">title</span>
<span class="go">&#39;SubFolder2&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">subfolders</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">album_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">title</span>
<span class="go">&#39;AlbumInFolder&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">subfolders</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">album_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">title</span>
<span class="go">&#39;SubFolder2&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span><span class="o">.</span><span class="n">folder_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">subfolders</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">album_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">album_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">title</span>
<span class="go">&#39;AlbumInFolder&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="a-name-placeinfo-placeinfo-a">
<h3><span class="raw-html-m2r"><a name="placeinfo">PlaceInfo</a></span><a class="headerlink" href="#a-name-placeinfo-placeinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#place">PhotoInfo.place</a> returns a PlaceInfo object if the photo contains valid reverse geolocation information.  PlaceInfo has the following properties.</p>
<p><strong>Note</strong> For Photos versions &lt;= 4, only <code class="docutils literal notranslate"><span class="pre">name</span></code>, <code class="docutils literal notranslate"><span class="pre">names</span></code>, and <code class="docutils literal notranslate"><span class="pre">country_code</span></code> properties are defined.  All others return <code class="docutils literal notranslate"><span class="pre">None</span></code>.  This is because older versions of Photos do not store the more detailed reverse geolocation information.</p>
<section id="a-name-ishome-ishome-a">
<h4><span class="raw-html-m2r"><a name="ishome">ishome</a></span><a class="headerlink" href="#a-name-ishome-ishome-a" title="Link to this heading">¶</a></h4>
<p>Returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if photo place is user's home address, otherwise <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
</section>
<section id="a-name-name-name-a">
<h4><span class="raw-html-m2r"><a name="name">name</a></span><a class="headerlink" href="#a-name-name-name-a" title="Link to this heading">¶</a></h4>
<p>Returns the name of the local place as str.  This is what Photos displays in the Info window.  <strong>Note</strong> Photos 5 uses a different algorithm to determine the name than earlier versions which means the same Photo may have a different place name in Photos 4 and Photos 5. <code class="docutils literal notranslate"><span class="pre">PhotoInfo.name</span></code> will return the name Photos would have shown depending on the version of the library being processed.  In Photos 5, the place name is generally more detailed than in earlier versions of Photos.</p>
<p>For example, I have photo in my library that under Photos 4, has place name of &quot;‎⁨Mayfair Shopping Centre⁩, ⁨Victoria⁩, ⁨Canada⁩&quot; and under Photos 5 the same photo has place name of &quot;Mayfair⁩, ⁨Vancouver Island⁩, ⁨Victoria⁩, ⁨British Columbia⁩, ⁨Canada⁩&quot;.</p>
<p>Returns <code class="docutils literal notranslate"><span class="pre">None</span></code> if photo does not contain a name.</p>
</section>
<section id="a-name-names-names-a">
<h4><span class="raw-html-m2r"><a name="names">names</a></span><a class="headerlink" href="#a-name-names-names-a" title="Link to this heading">¶</a></h4>
<p>Returns a <code class="docutils literal notranslate"><span class="pre">PlaceNames</span></code> namedtuple with the following fields.  Each field is a list with zero or more values, sorted by area in ascending order.  E.g. <code class="docutils literal notranslate"><span class="pre">names.area_of_interest</span></code> could be ['Gulf Islands National Seashore', 'Santa Rosa Island'], [&quot;Knott's Berry Farm&quot;], or [] if <code class="docutils literal notranslate"><span class="pre">area_of_interest</span></code> not defined.  The value shown in Photos is the first value in the list. With the exception of <code class="docutils literal notranslate"><span class="pre">body_of_water</span></code> each of these field corresponds to an attribute of a <a class="reference external" href="https://developer.apple.com/documentation/corelocation/clplacemark">CLPlacemark</a> object.  <strong>Note</strong> The <code class="docutils literal notranslate"><span class="pre">PlaceNames</span></code> namedtuple contains reserved fields not listed below (see implementation for details), thus it should be referenced only by name (e.g. <code class="docutils literal notranslate"><span class="pre">names.city</span></code>) and not by index.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">country</span></code>; the name of the country associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">state_province</span></code>; administrativeArea, The state or province associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_administrative_area</span></code>; additional administrative area information for the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">city</span></code>; locality; the city associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">additional_city_info</span></code>; subLocality, Additional city-level information for the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ocean</span></code>; the name of the ocean associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">area_of_interest</span></code>; areasOfInterest, The relevant areas of interest associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">inland_water</span></code>; the name of the inland water body associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">region</span></code>; the geographic region associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_throughfare</span></code>; additional street-level information for the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">postal_code</span></code>; the postal code associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">street_address</span></code>; throughfare, The street address associated with the placemark.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">body_of_water</span></code>; in Photos 4, any body of water; in Photos 5 contains the union of ocean and inland_water</p></li>
</ul>
<p><strong>Note</strong>: In Photos &lt;= 4.0, only the following fields are defined; all others are set to empty list:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">country</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">state_province</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_administrative_area</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">city</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">additional_city_info</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">area_of_interest</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">body_of_water</span></code></p></li>
</ul>
</section>
<section id="a-name-country-code-country-code-a">
<h4><span class="raw-html-m2r"><a name="country-code">country_code</a></span><a class="headerlink" href="#a-name-country-code-country-code-a" title="Link to this heading">¶</a></h4>
<p>Returns the country_code of place, for example &quot;GB&quot;.  Returns <code class="docutils literal notranslate"><span class="pre">None</span></code> if PhotoInfo contains no country code.</p>
</section>
<section id="a-name-address-str-address-str-a">
<h4><span class="raw-html-m2r"><a name="address-str">address_str</a></span><a class="headerlink" href="#a-name-address-str-address-str-a" title="Link to this heading">¶</a></h4>
<p>Returns the full postal address as a string if defined, otherwise <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
<p>For example: &quot;2038 18th St NW, Washington, DC  20009, United States&quot;</p>
</section>
<section id="a-name-address-address-a">
<h4><span class="raw-html-m2r"><a name="address">address</a></span><a class="headerlink" href="#a-name-address-address-a" title="Link to this heading">¶</a></h4>
<p>Returns a <code class="docutils literal notranslate"><span class="pre">PostalAddress</span></code> namedtuple with details of the postal address containing the following fields:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">city</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">country</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">postal_code</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">state</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">street</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_administrative_area</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sub_locality</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">iso_country_code</span></code></p></li>
</ul>
<p>For example:</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">photo</span><span class="o">.</span><span class="n">place</span><span class="o">.</span><span class="n">address</span>
<span class="go">PostalAddress(street=&#39;3700 Wailea Alanui Dr&#39;, sub_locality=None, city=&#39;Kihei&#39;, sub_administrative_area=&#39;Maui&#39;, state=&#39;HI&#39;, postal_code=&#39;96753&#39;, country=&#39;United States&#39;, iso_country_code=&#39;US&#39;)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photo</span><span class="o">.</span><span class="n">place</span><span class="o">.</span><span class="n">address</span><span class="o">.</span><span class="n">postal_code</span>
<span class="go">&#39;96753&#39;</span>
</pre></div>
</div>
</section>
</section>
<section id="a-name-scoreinfo-scoreinfo-a">
<h3><span class="raw-html-m2r"><a name="scoreinfo">ScoreInfo</a></span><a class="headerlink" href="#a-name-scoreinfo-scoreinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#score">PhotoInfo.score</a> returns a ScoreInfo object that exposes the computed aesthetic scores for each photo (<strong>Photos 5+ only</strong>).  I have not yet reverse engineered the meaning of each score.  The <code class="docutils literal notranslate"><span class="pre">overall</span></code> score seems to the most useful and appears to be a composite of the other scores.  The following score properties are currently available:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">overall</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">curation</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">promotion</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">highlight_visibility</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">behavioral</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">failure</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">harmonious_color</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">immersiveness</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">interaction</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">interesting_subject</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">intrusive_object_presence</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">lively_color</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">low_light</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">noise</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_camera_tilt</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_composition</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_lighting</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_pattern</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_perspective</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_post_processing</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_reflection</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">pleasant_symmetry</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">sharply_focused_subject</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">tastefully_blurred</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">well_chosen_subject</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">well_framed_subject</span><span class="p">:</span> <span class="nb">float</span>
<span class="n">well_timed_shot</span><span class="p">:</span> <span class="nb">float</span>
</pre></div>
</div>
<p>Example: find your &quot;best&quot; photo of food</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photos</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">best_food_photo</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">([</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="s2">&quot;food&quot;</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">labels_normalized</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">score</span><span class="o">.</span><span class="n">overall</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
</section>
<section id="a-name-searchinfo-searchinfo-a">
<h3><span class="raw-html-m2r"><a name="searchinfo">SearchInfo</a></span><a class="headerlink" href="#a-name-searchinfo-searchinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photosearchinfo">PhotoInfo.search_info</a> and <a class="reference external" href="#photosearchinfo-normalized">PhotoInfo.search_info_normalized</a> return a SearchInfo object that exposes various metadata that Photos uses when searching for photos such as labels, associated holiday, etc. (<strong>Photos 5+ only</strong>).</p>
<p>The following properties are available:</p>
<section id="a-name-searchinfo-labels-labels-a">
<h4><span class="raw-html-m2r"><a name="searchinfo-labels">labels</a></span><a class="headerlink" href="#a-name-searchinfo-labels-labels-a" title="Link to this heading">¶</a></h4>
<p>Returns list of labels applied to photo by Photos image categorization algorithms.</p>
</section>
<section id="a-name-place-names-place-names-a">
<h4><span class="raw-html-m2r"><a name="place-names">place_names</a></span><a class="headerlink" href="#a-name-place-names-place-names-a" title="Link to this heading">¶</a></h4>
<p>Returns list of place names associated with the photo.</p>
</section>
<section id="a-name-streets-streets-a">
<h4><span class="raw-html-m2r"><a name="streets">streets</a></span><a class="headerlink" href="#a-name-streets-streets-a" title="Link to this heading">¶</a></h4>
<p>Returns list of street names associated with the photo. (e.g. reverse geolocation of where the photo was taken)</p>
</section>
<section id="a-name-neighborhoods-neighborhoods-a">
<h4><span class="raw-html-m2r"><a name="neighborhoods">neighborhoods</a></span><a class="headerlink" href="#a-name-neighborhoods-neighborhoods-a" title="Link to this heading">¶</a></h4>
<p>Returns list of neighborhood names associated with the photo.</p>
</section>
<section id="a-name-locality-names-locality-names-a">
<h4><span class="raw-html-m2r"><a name="locality-names">locality_names</a></span><a class="headerlink" href="#a-name-locality-names-locality-names-a" title="Link to this heading">¶</a></h4>
<p>Returns list of locality names associated with the photo.</p>
</section>
<section id="a-name-city-city-a">
<h4><span class="raw-html-m2r"><a name="city">city</a></span><a class="headerlink" href="#a-name-city-city-a" title="Link to this heading">¶</a></h4>
<p>Returns str of city/town/municipality associated with the photo.</p>
</section>
<section id="a-name-state-state-a">
<h4><span class="raw-html-m2r"><a name="state">state</a></span><a class="headerlink" href="#a-name-state-state-a" title="Link to this heading">¶</a></h4>
<p>Returns str of state name associated with the photo.</p>
</section>
<section id="a-name-state-abbreviation-state-abbreviation-a">
<h4><span class="raw-html-m2r"><a name="state-abbreviation">state_abbreviation</a></span><a class="headerlink" href="#a-name-state-abbreviation-state-abbreviation-a" title="Link to this heading">¶</a></h4>
<p>Returns str of state abbreviation associated with the photo.</p>
</section>
<section id="a-name-country-country-a">
<h4><span class="raw-html-m2r"><a name="country">country</a></span><a class="headerlink" href="#a-name-country-country-a" title="Link to this heading">¶</a></h4>
<p>Returns str of country name associated with the photo.</p>
</section>
<section id="a-name-month-month-a">
<h4><span class="raw-html-m2r"><a name="month">month</a></span><a class="headerlink" href="#a-name-month-month-a" title="Link to this heading">¶</a></h4>
<p>Returns str of month name associated witht the photo (e.g. month in which the photo was taken)</p>
</section>
<section id="a-name-year-year-a">
<h4><span class="raw-html-m2r"><a name="year">year</a></span><a class="headerlink" href="#a-name-year-year-a" title="Link to this heading">¶</a></h4>
<p>Returns year associated with the photo.</p>
</section>
<section id="a-name-bodies-of-water-bodies-of-water-a">
<h4><span class="raw-html-m2r"><a name="bodies-of-water">bodies_of_water</a></span><a class="headerlink" href="#a-name-bodies-of-water-bodies-of-water-a" title="Link to this heading">¶</a></h4>
<p>Returns list of bodies of water associated with the photo.</p>
</section>
<section id="a-name-holidays-holidays-a">
<h4><span class="raw-html-m2r"><a name="holidays">holidays</a></span><a class="headerlink" href="#a-name-holidays-holidays-a" title="Link to this heading">¶</a></h4>
<p>Returns list of holiday names associated with the photo.</p>
</section>
<section id="a-name-activities-activities-a">
<h4><span class="raw-html-m2r"><a name="activities">activities</a></span><a class="headerlink" href="#a-name-activities-activities-a" title="Link to this heading">¶</a></h4>
<p>Returns list of activities associated with the photo.</p>
</section>
<section id="a-name-season-season-a">
<h4><span class="raw-html-m2r"><a name="season">season</a></span><a class="headerlink" href="#a-name-season-season-a" title="Link to this heading">¶</a></h4>
<p>Returns str of season name associated with the photo.</p>
</section>
<section id="a-name-venues-venues-a">
<h4><span class="raw-html-m2r"><a name="venues">venues</a></span><a class="headerlink" href="#a-name-venues-venues-a" title="Link to this heading">¶</a></h4>
<p>Returns list of venue names associated with the photo.</p>
</section>
<section id="a-name-venue-types-venue-types-a">
<h4><span class="raw-html-m2r"><a name="venue-types">venue_types</a></span><a class="headerlink" href="#a-name-venue-types-venue-types-a" title="Link to this heading">¶</a></h4>
<p>Returns list of venue types associated with the photoo.</p>
</section>
<section id="a-name-media-types-media-types-a">
<h4><span class="raw-html-m2r"><a name="media-types">media_types</a></span><a class="headerlink" href="#a-name-media-types-media-types-a" title="Link to this heading">¶</a></h4>
<p>Returns list of media types associated with the photo.</p>
</section>
<section id="a-name-all-all-a">
<h4><span class="raw-html-m2r"><a name="all">all</a></span><a class="headerlink" href="#a-name-all-all-a" title="Link to this heading">¶</a></h4>
<p>Returns all search_info properties as a single list of strings.</p>
</section>
<section id="id91">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id91" title="Link to this heading">¶</a></h4>
<p>Returns all associated search_info metadata as a dict.</p>
</section>
</section>
<section id="a-name-personinfo-personinfo-a">
<h3><span class="raw-html-m2r"><a name="personinfo">PersonInfo</a></span><a class="headerlink" href="#a-name-personinfo-personinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photosdb-person-info">PhotosDB.person_info</a> and <a class="reference external" href="#photoinfo-person-info">PhotoInfo.person_info</a> return a list of PersonInfo objects represents persons in the database and in a photo, respectively.  The PersonInfo class has the following properties and methods.</p>
<section id="id92">
<h4><span class="raw-html-m2r"><a name="name">name</a></span><a class="headerlink" href="#id92" title="Link to this heading">¶</a></h4>
<p>Returns the full name of the person represented in the photo. For example, &quot;Maria Smith&quot;.</p>
</section>
<section id="a-name-display-name-display-name-a">
<h4><span class="raw-html-m2r"><a name="display-name">display_name</a></span><a class="headerlink" href="#a-name-display-name-display-name-a" title="Link to this heading">¶</a></h4>
<p>Returns the display name of the person represented in the photo. For example, &quot;Maria&quot;.</p>
</section>
<section id="a-name-personinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="personinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-personinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>Returns the UUID of the person as stored in the Photos library database.</p>
</section>
<section id="a-name-keyphoto-keyphoto-a">
<h4><span class="raw-html-m2r"><a name="keyphoto">keyphoto</a></span><a class="headerlink" href="#a-name-keyphoto-keyphoto-a" title="Link to this heading">¶</a></h4>
<p>Returns a PhotoInfo instance for the photo designated as the key photo for the person. This is the Photos uses to display the person's face thumbnail in Photos' &quot;People&quot; view.</p>
</section>
<section id="a-name-facecount-facecount-a">
<h4><span class="raw-html-m2r"><a name="facecount">facecount</a></span><a class="headerlink" href="#a-name-facecount-facecount-a" title="Link to this heading">¶</a></h4>
<p>Returns a count of how many times this person appears in images in the database.</p>
</section>
<section id="a-name-personphotos-photos-a">
<h4><span class="raw-html-m2r"><a name="personphotos">photos</a></span><a class="headerlink" href="#a-name-personphotos-photos-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of PhotoInfo objects representing all photos the person appears in.</p>
</section>
<section id="a-name-person-face-info-face-info-a">
<h4><span class="raw-html-m2r"><a name="person-face-info">face_info</a></span><a class="headerlink" href="#a-name-person-face-info-face-info-a" title="Link to this heading">¶</a></h4>
<p>Returns a list of <a class="reference external" href="#faceinfo">FaceInfo</a> objects associated with this person sorted by quality score. Highest quality face is result[0] and lowest quality face is result[n].</p>
</section>
<section id="a-name-personfavorite-favorite-a">
<h4><span class="raw-html-m2r"><a name="personfavorite">favorite</a></span><a class="headerlink" href="#a-name-personfavorite-favorite-a" title="Link to this heading">¶</a></h4>
<p>Returns True if Person has been marked as a favorite in Photos, otherwise False. Available on Photos 5+ only; on Photos &lt;=4, returns False.</p>
</section>
<section id="a-name-personsortorder-sort-order-a">
<h4><span class="raw-html-m2r"><a name="personsortorder">sort_order</a></span><a class="headerlink" href="#a-name-personsortorder-sort-order-a" title="Link to this heading">¶</a></h4>
<p>Returns the sort order for the person in the Photos People view.  Available on Photos 5+ only; on Photos &lt;= 4, returns None.</p>
</section>
<section id="id94">
<h4><span class="raw-html-m2r"><a name="json">json()</a></span><a class="headerlink" href="#id94" title="Link to this heading">¶</a></h4>
<p>Returns a json string representation of the PersonInfo instance.</p>
</section>
<section id="id95">
<h4><span class="raw-html-m2r"><a name="asdict">asdict()</a></span><a class="headerlink" href="#id95" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the PersonInfo instance.</p>
</section>
</section>
<section id="a-name-faceinfo-faceinfo-a">
<h3><span class="raw-html-m2r"><a name="faceinfo">FaceInfo</a></span><a class="headerlink" href="#a-name-faceinfo-faceinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photoinfo-face-info">PhotoInfo.face_info</a> return a list of FaceInfo objects representing detected faces in a photo.  The FaceInfo class has the following properties and methods.</p>
<section id="a-name-faceinfo-uuid-uuid-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-uuid">uuid</a></span><a class="headerlink" href="#a-name-faceinfo-uuid-uuid-a" title="Link to this heading">¶</a></h4>
<p>UUID of the face.</p>
</section>
<section id="a-name-faceinfo-name-name-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-name">name</a></span><a class="headerlink" href="#a-name-faceinfo-name-name-a" title="Link to this heading">¶</a></h4>
<p>Full name of the person represented by the face or None if person hasn't been given a name in Photos.  This is a shortcut for <code class="docutils literal notranslate"><span class="pre">FaceInfo.person_info.name</span></code>.</p>
</section>
<section id="a-name-asset-uuid-asset-uuid-a">
<h4><span class="raw-html-m2r"><a name="asset-uuid">asset_uuid</a></span><a class="headerlink" href="#a-name-asset-uuid-asset-uuid-a" title="Link to this heading">¶</a></h4>
<p>UUID of the photo this face is associated with.</p>
</section>
<section id="a-name-faceinfo-person-info-person-info-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-person-info">person_info</a></span><a class="headerlink" href="#a-name-faceinfo-person-info-person-info-a" title="Link to this heading">¶</a></h4>
<p><a class="reference external" href="#personinfo">PersonInfo</a> object associated with this face.</p>
</section>
<section id="a-name-faceinfo-photo-photo-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-photo">photo</a></span><a class="headerlink" href="#a-name-faceinfo-photo-photo-a" title="Link to this heading">¶</a></h4>
<p><a class="reference external" href="#photoinfo">PhotoInfo</a> object representing the photo that contains this face.</p>
</section>
<section id="a-name-mwg-rs-area-mwg-rs-area-a">
<h4><span class="raw-html-m2r"><a name="mwg-rs-area">mwg_rs_area</a></span><a class="headerlink" href="#a-name-mwg-rs-area-mwg-rs-area-a" title="Link to this heading">¶</a></h4>
<p>Returns named tuple with following coordinates as used in Metdata Working Group (mwg) face regions in XMP files.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">x</span></code> = <code class="docutils literal notranslate"><span class="pre">stArea:x</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">y</span></code> = <code class="docutils literal notranslate"><span class="pre">stArea:y</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">h</span></code> = <code class="docutils literal notranslate"><span class="pre">stArea:h</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">w</span></code> = <code class="docutils literal notranslate"><span class="pre">stArea:w</span></code></p></li>
</ul>
</section>
<section id="a-name-mpri-reg-rect-mpri-reg-rect-a">
<h4><span class="raw-html-m2r"><a name="mpri-reg-rect">mpri_reg_rect</a></span><a class="headerlink" href="#a-name-mpri-reg-rect-mpri-reg-rect-a" title="Link to this heading">¶</a></h4>
<p>Returnes named tuple with following coordinates as used in Microsoft Photo Region Rectangle (mpri) in XMP files.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">x</span></code> = x coordinate of top left corner of rectangle</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">y</span></code> = y coordinate of top left corner of rectangle</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">h</span></code> = height of rectangle</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">w</span></code> = width of rectangle</p></li>
</ul>
</section>
<section id="a-name-face-rect-face-rect-a">
<h4><span class="raw-html-m2r"><a name="face-rect">face_rect()</a></span><a class="headerlink" href="#a-name-face-rect-face-rect-a" title="Link to this heading">¶</a></h4>
<p>Returns list of x, y coordinates as tuples <code class="docutils literal notranslate"><span class="pre">[(x0,</span> <span class="pre">y0),</span> <span class="pre">(x1,</span> <span class="pre">y1)]</span></code> representing the corners of rectangular region that contains the face.  Coordinates are in same format and <a class="reference external" href="https://pillow.readthedocs.io/en/stable/handbook/concepts.html#coordinate-system">reference frame</a> as used by <a class="reference external" href="https://pypi.org/project/Pillow/">Pillow</a> imaging library.  <strong>Note</strong>: face_rect() and all other properties/methods that return coordinates refer to the <em>current version</em> of the image. E.g. if the image has been edited (<a class="reference external" href="#hasadjustments">PhotoInfo.hasadjustments</a>), these refer to <a class="reference external" href="#path-edited">PhotoInfo.path_edited</a>.  If the image has no adjustments, these coordinates refer to the original photo (<a class="reference external" href="#path">PhotoInfo.path</a>).</p>
</section>
<section id="a-name-center-center-a">
<h4><span class="raw-html-m2r"><a name="center">center</a></span><a class="headerlink" href="#a-name-center-center-a" title="Link to this heading">¶</a></h4>
<p>Coordinates as (x, y) tuple for the center of the detected face.</p>
</section>
<section id="a-name-size-pixels-size-pixels-a">
<h4><span class="raw-html-m2r"><a name="size-pixels">size_pixels</a></span><a class="headerlink" href="#a-name-size-pixels-size-pixels-a" title="Link to this heading">¶</a></h4>
<p>Diameter of detected face region in pixels.</p>
</section>
<section id="a-name-roll-pitch-yaw-roll-pitch-yaw-a">
<h4><span class="raw-html-m2r"><a name="roll-pitch-yaw">roll_pitch_yaw()</a></span><a class="headerlink" href="#a-name-roll-pitch-yaw-roll-pitch-yaw-a" title="Link to this heading">¶</a></h4>
<p>Roll, pitch, and yaw of face region in radians.  Returns a tuple of (roll, pitch, yaw)</p>
</section>
<section id="a-name-roll-roll-a">
<h4><span class="raw-html-m2r"><a name="roll">roll</a></span><a class="headerlink" href="#a-name-roll-roll-a" title="Link to this heading">¶</a></h4>
<p>Roll of face region in radians.</p>
</section>
<section id="a-name-pitch-pitch-a">
<h4><span class="raw-html-m2r"><a name="pitch">pitch</a></span><a class="headerlink" href="#a-name-pitch-pitch-a" title="Link to this heading">¶</a></h4>
<p>Pitch of face region in radians.</p>
<p><strong>Note</strong>: Only valid on Photos version &lt;= 4, otherwise returns 0</p>
</section>
<section id="a-name-yaw-yaw-a">
<h4><span class="raw-html-m2r"><a name="yaw">yaw</a></span><a class="headerlink" href="#a-name-yaw-yaw-a" title="Link to this heading">¶</a></h4>
<p>Yaw of face region in radians.</p>
<p><strong>Note</strong>: Only valid on Photos version &lt;= 4, otherwise returns 0</p>
</section>
<section id="additional-properties">
<h4>Additional properties<a class="headerlink" href="#additional-properties" title="Link to this heading">¶</a></h4>
<p>The following additional properties are also available but are not yet fully documented.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">center_x</span></code>: x coordinate of center of face in Photos' internal reference frame</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">center_y</span></code>: y coordinate of center of face in Photos' internal reference frame</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">size</span></code>: size of face region in Photos' internal reference frame</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">quality</span></code>: quality measure of detected face</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">source_width</span></code>: width in pixels of photo</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">source_height</span></code>: height in pixels of photo</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">has_smile</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">manual</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">face_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">age_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">eye_makeup_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">eye_state</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">facial_hair_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">gender_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">glasses_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">hair_color_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lip_makeup_type</span></code>:</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">smile_type</span></code>:</p></li>
</ul>
</section>
<section id="a-name-faceinfo-asdict-asdict-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-asdict">asdict()</a></span><a class="headerlink" href="#a-name-faceinfo-asdict-asdict-a" title="Link to this heading">¶</a></h4>
<p>Returns a dictionary representation of the FaceInfo instance.</p>
</section>
<section id="a-name-faceinfo-json-json-a">
<h4><span class="raw-html-m2r"><a name="faceinfo-json">json()</a></span><a class="headerlink" href="#a-name-faceinfo-json-json-a" title="Link to this heading">¶</a></h4>
<p>Returns a JSON representation of the FaceInfo instance.</p>
</section>
</section>
<section id="a-name-commentinfo-commentinfo-a">
<h3><span class="raw-html-m2r"><a name="commentinfo">CommentInfo</a></span><a class="headerlink" href="#a-name-commentinfo-commentinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#comments">PhotoInfo.comments</a> returns a list of CommentInfo objects for comments on shared photos. (Photos 5/MacOS 10.15+ only).  The list of CommentInfo objects will be sorted in ascending order by date comment was made.  CommentInfo contains the following fields:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">datetime</span></code>: <code class="docutils literal notranslate"><span class="pre">datetime.datetime</span></code>, date/time comment was made</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">user</span></code>: <code class="docutils literal notranslate"><span class="pre">str</span></code>, name of user who made the comment</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ismine</span></code>: <code class="docutils literal notranslate"><span class="pre">bool</span></code>, True if comment was made by person who owns the Photos library being operated on</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">text</span></code>: <code class="docutils literal notranslate"><span class="pre">str</span></code>, text of the actual comment</p></li>
</ul>
</section>
<section id="a-name-likeinfo-likeinfo-a">
<h3><span class="raw-html-m2r"><a name="likeinfo">LikeInfo</a></span><a class="headerlink" href="#a-name-likeinfo-likeinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#likes">PhotoInfo.likes</a> returns a list of LikeInfo objects for &quot;likes&quot; on shared photos. (Photos 5/MacOS 10.15+ only).  The list of LikeInfo objects will be sorted in ascending order by date like was made.  LikeInfo contains the following fields:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">datetime</span></code>: <code class="docutils literal notranslate"><span class="pre">datetime.datetime</span></code>, date/time like was made</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">user</span></code>: <code class="docutils literal notranslate"><span class="pre">str</span></code>, name of user who made the like</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ismine</span></code>: <code class="docutils literal notranslate"><span class="pre">bool</span></code>, True if like was made by person who owns the Photos library being operated on</p></li>
</ul>
</section>
<section id="a-name-adjustmentsinfo-adjustmentsinfo-a">
<h3><span class="raw-html-m2r"><a name="adjustmentsinfo">AdjustmentsInfo</a></span><a class="headerlink" href="#a-name-adjustmentsinfo-adjustmentsinfo-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#adjustments">PhotoInfo.adjustments</a> returns an AdjustmentsInfo object, if the photo has adjustments, or <code class="docutils literal notranslate"><span class="pre">None</span></code> if the photo does not have adjusments.   AdjustmentsInfo has the following properties and methods:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">plist</span></code>: The adjustments plist file maintained by Photos as a dict.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">data</span></code>: The raw, undecoded adjustments info as binary blob.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">editor</span></code>: The editor bundle ID of the app which made the edits, e.g. <code class="docutils literal notranslate"><span class="pre">com.apple.photos</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">format_id</span></code>: The format identifier set by the app which made the edits, e.g. <code class="docutils literal notranslate"><span class="pre">com.apple.photos</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">base_version</span></code>: Version info set by the app which made the edits.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">format_version</span></code>: Version info set by the app which made the edits.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">timestamp</span></code>: Time stamp of the adjustment as a timezone-aware datetime.datetime object; None if no timestamp is set.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">adjustments</span></code>: a list of dicts containing information about the decoded adjustments to the photo or None if adjustments could not be decoded. AdjustmentsInfo can decode adjustments made by Photos but cannot decode adjustments made by external plugins or apps.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">adj_metadata</span></code>: a dict containing additional data about the photo decoded from the adjustment data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">adj_orientation</span></code>: the EXIF orientation of the edited photo decoded from the adjustment metadata.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">adj_format_version</span></code>: version for adjustments format decoded from the adjustment data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">adj_version_info</span></code>: version info for the application which made the adjustments to the photo decoded from the adjustments data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">asdict()</span></code>: dict representation of the AdjustmentsInfo object; contains all properties with exception of <code class="docutils literal notranslate"><span class="pre">plist</span></code>.</p></li>
</ul>
</section>
<section id="a-name-phototables-phototables-a">
<h3><span class="raw-html-m2r"><a name="phototables">PhotoTables</a></span><a class="headerlink" href="#a-name-phototables-phototables-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#tables">PhotoInfo.tables</a> returns a PhotoTables object that contains information about the tables in the Photos database that contain information about the photo.
The following properties are available:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">ZASSET</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ZADDITIONALASSETATTRIBUTES</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ZDETECTEDFACE</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ZPERSON</span></code></p></li>
</ul>
<p>Each of these properties returns a <code class="docutils literal notranslate"><span class="pre">Table</span></code> object that provides access to the row(s) in the table that correspond to the photo.</p>
<p>The Table object has dynamically created properties that correspond to the associated column in the table and return a tuple of values for that column.</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">photo</span><span class="o">.</span><span class="n">tables</span><span class="p">()</span><span class="o">.</span><span class="n">ZADDITIONALASSETATTRIBUTES</span><span class="o">.</span><span class="n">ZTITLE</span>
<span class="go">(&quot;St. James&#39;s Park&quot;,)</span>
</pre></div>
</div>
<p>The Table object also provides a <code class="docutils literal notranslate"><span class="pre">rows()</span></code> method which returns a list a of tuples for the matching rows in the table
and a <code class="docutils literal notranslate"><span class="pre">rows_dict()</span></code> method which returns a list of dicts for the matching rows in the table.</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">photo</span><span class="o">.</span><span class="n">tables</span><span class="p">()</span><span class="o">.</span><span class="n">ZASSET</span><span class="o">.</span><span class="n">rows</span><span class="p">()</span>
<span class="go">[(6, 3, 35, 0, 0, 0, 0, 0, 0, None, None, None, None, None, 0, 0, 1, 0, 0, 0, 0, -100, 0, 1, 0, 1356, 0, 0, 0, 0, 0, 0, 0, 1, 6192599813128215, 1, 2814835671629878, 1, 0, 3, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 2047, 7, None, 8, None, None, None, None, None, None, None, None, 3, 6, 6, 6, None, 6, 4, None, None, 8, 4, None, 2, None, 3, None, 3, None, None, 585926209.859624, 596906868.198932, 689981763.374756, None, None, None, 0.5, 561129492.501, 0.0, 596906868.198932, None, 0.03816793893129771, None, 51.50357167, -0.1318055, 689982854.802854, 0.6494140625, 0.0, 561129492.501, None, None, None, None, None, None, None, &#39;D&#39;, &#39;DC99FBDD-7A52-4100-A5BB-344131646C30.jpeg&#39;, None, &#39;sRGB IEC61966-2.1&#39;, &#39;public.jpeg&#39;, &#39;DC99FBDD-7A52-4100-A5BB-344131646C30&#39;, b&#39;Ki\t@\x01\x00\x00\x00\td\tH\x01\x00\x00\x00\x93\\\tL\x01\x00\x00\x00\x1aK\x0c\x03\x0c\xa8q\x92\x00\x12C\x0c\x03\x0c&quot;\r\x90\x00\x00&lt;\x0c\x03\x08&quot;\x19\x80\x00&#39;, b&#39;\xca\xebV\tu\xc0I@/j\xf7\xab\x00\xdf\xc0\xbf\xcd\xcc\xcc\xcc\xcc\xcc\x04@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&#39;)]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">photo</span><span class="o">.</span><span class="n">tables</span><span class="p">()</span><span class="o">.</span><span class="n">ZASSET</span><span class="o">.</span><span class="n">rows_dict</span><span class="p">()</span>
<span class="go">[{&#39;Z_PK&#39;: 6, &#39;Z_ENT&#39;: 3, &#39;Z_OPT&#39;: 35, &#39;ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE&#39;: 0, &#39;ZAVALANCHEPICKTYPE&#39;: 0, &#39;ZBUNDLESCOPE&#39;: 0, &#39;ZCAMERAPROCESSINGADJUSTMENTSTATE&#39;: 0, &#39;ZCLOUDDELETESTATE&#39;: 0, &#39;ZCLOUDDOWNLOADREQUESTS&#39;: 0, &#39;ZCLOUDHASCOMMENTSBYME&#39;: None, &#39;ZCLOUDHASCOMMENTSCONVERSATION&#39;: None, &#39;ZCLOUDHASUNSEENCOMMENTS&#39;: None, &#39;ZCLOUDISDELETABLE&#39;: None, &#39;ZCLOUDISMYASSET&#39;: None, &#39;ZCLOUDLOCALSTATE&#39;: 0, &#39;ZCLOUDPLACEHOLDERKIND&#39;: 0, &#39;ZCOMPLETE&#39;: 1, &#39;ZDEFERREDPROCESSINGNEEDED&#39;: 0, &#39;ZDEPTHTYPE&#39;: 0, &#39;ZDERIVEDCAMERACAPTUREDEVICE&#39;: 0, &#39;ZDUPLICATEASSETVISIBILITYSTATE&#39;: 0, &#39;ZFACEAREAPOINTS&#39;: -100, &#39;ZFAVORITE&#39;: 0, &#39;ZHASADJUSTMENTS&#39;: 1, &#39;ZHDRTYPE&#39;: 0, &#39;ZHEIGHT&#39;: 1356, &#39;ZHIDDEN&#39;: 0, &#39;ZHIGHFRAMERATESTATE&#39;: 0, &#39;ZISMAGICCARPET&#39;: 0, &#39;ZKIND&#39;: 0, &#39;ZKINDSUBTYPE&#39;: 0, &#39;ZLIBRARYSCOPESHARESTATE&#39;: 0, &#39;ZMONOSKITYPE&#39;: 0, &#39;ZORIENTATION&#39;: 1, &#39;ZPACKEDACCEPTABLECROPRECT&#39;: 6192599813128215, &#39;ZPACKEDBADGEATTRIBUTES&#39;: 1, &#39;ZPACKEDPREFERREDCROPRECT&#39;: 2814835671629878, &#39;ZPLAYBACKSTYLE&#39;: 1, &#39;ZPLAYBACKVARIATION&#39;: 0, &#39;ZSAVEDASSETTYPE&#39;: 3, &#39;ZSEARCHINDEXREBUILDSTATE&#39;: 0, &#39;ZSYNDICATIONSTATE&#39;: 0, &#39;ZTHUMBNAILINDEX&#39;: 5, &#39;ZTRASHEDSTATE&#39;: 0, &#39;ZVIDEOCPDURATIONVALUE&#39;: 0, &#39;ZVIDEOCPVISIBILITYSTATE&#39;: 0, &#39;ZVIDEODEFERREDPROCESSINGNEEDED&#39;: 0, &#39;ZVIDEOKEYFRAMETIMESCALE&#39;: 0, &#39;ZVIDEOKEYFRAMEVALUE&#39;: 0, &#39;ZVISIBILITYSTATE&#39;: 0, &#39;ZWIDTH&#39;: 2047, &#39;ZADDITIONALATTRIBUTES&#39;: 7, &#39;ZCLOUDFEEDASSETSENTRY&#39;: None, &#39;ZCOMPUTEDATTRIBUTES&#39;: 8, &#39;ZCONVERSATION&#39;: None, &#39;ZDAYGROUPHIGHLIGHTBEINGASSETS&#39;: None, &#39;ZDAYGROUPHIGHLIGHTBEINGEXTENDEDASSETS&#39;: None, &#39;ZDAYGROUPHIGHLIGHTBEINGKEYASSETPRIVATE&#39;: None, &#39;ZDAYGROUPHIGHLIGHTBEINGKEYASSETSHARED&#39;: None, &#39;ZDAYGROUPHIGHLIGHTBEINGSUMMARYASSETS&#39;: None, &#39;ZDUPLICATEMETADATAMATCHINGALBUM&#39;: None, &#39;ZDUPLICATEPERCEPTUALMATCHINGALBUM&#39;: None, &#39;ZEXTENDEDATTRIBUTES&#39;: 3, &#39;ZHIGHLIGHTBEINGASSETS&#39;: 6, &#39;ZHIGHLIGHTBEINGEXTENDEDASSETS&#39;: 6, &#39;ZHIGHLIGHTBEINGKEYASSETPRIVATE&#39;: 6, &#39;ZHIGHLIGHTBEINGKEYASSETSHARED&#39;: None, &#39;ZHIGHLIGHTBEINGSUMMARYASSETS&#39;: 6, &#39;ZIMPORTSESSION&#39;: 4, &#39;ZLIBRARYSCOPE&#39;: None, &#39;ZMASTER&#39;: None, &#39;ZMEDIAANALYSISATTRIBUTES&#39;: 8, &#39;ZMOMENT&#39;: 4, &#39;ZMOMENTSHARE&#39;: None, &#39;ZMONTHHIGHLIGHTBEINGKEYASSETPRIVATE&#39;: 2, &#39;ZMONTHHIGHLIGHTBEINGKEYASSETSHARED&#39;: None, &#39;ZPHOTOANALYSISATTRIBUTES&#39;: 3, &#39;ZTRASHEDBYPARTICIPANT&#39;: None, &#39;ZYEARHIGHLIGHTBEINGKEYASSETPRIVATE&#39;: 3, &#39;ZYEARHIGHLIGHTBEINGKEYASSETSHARED&#39;: None, &#39;Z_FOK_CLOUDFEEDASSETSENTRY&#39;: None, &#39;ZADDEDDATE&#39;: 585926209.859624, &#39;ZADJUSTMENTTIMESTAMP&#39;: 596906868.198932, &#39;ZANALYSISSTATEMODIFICATIONDATE&#39;: 689981763.374756, &#39;ZCLOUDBATCHPUBLISHDATE&#39;: None, &#39;ZCLOUDLASTVIEWEDCOMMENTDATE&#39;: None, &#39;ZCLOUDSERVERPUBLISHDATE&#39;: None, &#39;ZCURATIONSCORE&#39;: 0.5, &#39;ZDATECREATED&#39;: 561129492.501, &#39;ZDURATION&#39;: 0.0, &#39;ZFACEADJUSTMENTVERSION&#39;: 596906868.198932, &#39;ZHDRGAIN&#39;: None, &#39;ZHIGHLIGHTVISIBILITYSCORE&#39;: 0.03816793893129771, &#39;ZLASTSHAREDDATE&#39;: None, &#39;ZLATITUDE&#39;: 51.50357167, &#39;ZLONGITUDE&#39;: -0.1318055, &#39;ZMODIFICATIONDATE&#39;: 689982854.802854, &#39;ZOVERALLAESTHETICSCORE&#39;: 0.6494140625, &#39;ZPROMOTIONSCORE&#39;: 0.0, &#39;ZSORTTOKEN&#39;: 561129492.501, &#39;ZTRASHEDDATE&#39;: None, &#39;ZAVALANCHEUUID&#39;: None, &#39;ZCLOUDASSETGUID&#39;: None, &#39;ZCLOUDBATCHID&#39;: None, &#39;ZCLOUDCOLLECTIONGUID&#39;: None, &#39;ZCLOUDOWNERHASHEDPERSONID&#39;: None, &#39;ZDELETEREASON&#39;: None, &#39;ZDIRECTORY&#39;: &#39;D&#39;, &#39;ZFILENAME&#39;: &#39;DC99FBDD-7A52-4100-A5BB-344131646C30.jpeg&#39;, &#39;ZMEDIAGROUPUUID&#39;: None, &#39;ZORIGINALCOLORSPACE&#39;: &#39;sRGB IEC61966-2.1&#39;, &#39;ZUNIFORMTYPEIDENTIFIER&#39;: &#39;public.jpeg&#39;, &#39;ZUUID&#39;: &#39;DC99FBDD-7A52-4100-A5BB-344131646C30&#39;, &#39;ZIMAGEREQUESTHINTS&#39;: b&#39;Ki\t@\x01\x00\x00\x00\td\tH\x01\x00\x00\x00\x93\\\tL\x01\x00\x00\x00\x1aK\x0c\x03\x0c\xa8q\x92\x00\x12C\x0c\x03\x0c&quot;\r\x90\x00\x00&lt;\x0c\x03\x08&quot;\x19\x80\x00&#39;, &#39;ZLOCATIONDATA&#39;: b&#39;\xca\xebV\tu\xc0I@/j\xf7\xab\x00\xdf\xc0\xbf\xcd\xcc\xcc\xcc\xcc\xcc\x04@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&#39;}]</span>
</pre></div>
</div>
</section>
<section id="a-name-raw-photos-raw-photos-a">
<h3><span class="raw-html-m2r"><a name="raw-photos">Raw Photos</a></span><a class="headerlink" href="#a-name-raw-photos-raw-photos-a" title="Link to this heading">¶</a></h3>
<p>Handling raw photos in <code class="docutils literal notranslate"><span class="pre">osxphotos</span></code> requires a bit of extra work.  Raw photos in Photos can be imported in two different ways: 1) a single raw photo with no associated JPEG image is imported 2) a raw+JPEG pair is imported -- two separate images with same file stem (e.g. <code class="docutils literal notranslate"><span class="pre">IMG_0001.CR2</span></code> and <code class="docutils literal notranslate"><span class="pre">IMG_001.JPG</span></code>) are imported.</p>
<p>The latter are treated by Photos as a single image.  By default, Photos will treat these as a JPEG image.  They are denoted in the Photos interface with a &quot;J&quot; icon superimposed on the image.  In Photos, the user can select &quot;Use RAW as original&quot; in which case the &quot;J&quot; icon changes to an &quot;R&quot; icon and all subsequent edits will use the raw image as the original. To further complicate this, different versions of Photos handle these differently in their internal logic.</p>
<p><code class="docutils literal notranslate"><span class="pre">osxphotos</span></code> attempts to simplify the handling of these raw+JPEG pairs by providing a set of attributes for accessing both the JPEG and the raw version.  For example, <a class="reference external" href="#has-raw">PhotoInfo.has_raw</a> will be True if the photo has an associated raw image but False otherwise and <a class="reference external" href="#path-raw">PhotoInfo.path_raw</a> provides the path to the associated raw image.  Reference the following table for the various attributes useful for dealing with raw images.  Given the different ways Photos deals with raw images I've struggled with how to represent these in a logical and consistent manner.  If you have suggestions for a better interface, please open an <a class="reference external" href="https://github.com/RhetTbull/osxphotos/issues">issue</a>!</p>
<section id="raw-related-attributes">
<h4>Raw-Related Attributes<a class="headerlink" href="#raw-related-attributes" title="Link to this heading">¶</a></h4>
<div class="table-wrapper docutils container">
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p><code class="docutils literal notranslate"><span class="pre">PhotoInfo</span></code> attribute</p></th>
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">IMG_0001.CR2</span></code> imported without raw+JPEG pair</p></th>
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">IMG_0001.CR2</span></code> + <code class="docutils literal notranslate"><span class="pre">IMG_0001.JPG</span></code> raw+JPEG pair, JPEG is original</p></th>
<th class="head"><p><code class="docutils literal notranslate"><span class="pre">IMG_0001.CR2</span></code> + <code class="docutils literal notranslate"><span class="pre">IMG_0001.JPG</span></code> raw+jpeg pair, raw is original</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><a class="reference external" href="#israw">israw</a></p></td>
<td><p>True</p></td>
<td><p>False</p></td>
<td><p>False</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference external" href="#has-raw">has_raw</a></p></td>
<td><p>False</p></td>
<td><p>True</p></td>
<td><p>True</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference external" href="#uti">uti</a></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">com.canon.cr2-raw-image</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">public.jpeg</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">public.jpeg</span></code></p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference external" href="#uti-raw">uti_raw</a></p></td>
<td><p>None</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">com.canon.cr2-raw-image</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">com.canon.cr2-raw-image</span></code></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference external" href="#raw-original">raw_original</a></p></td>
<td><p>False</p></td>
<td><p>False</p></td>
<td><p>True</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference external" href="#path">path</a></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">/path/to/IMG_0001.CR2</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">/path/to/IMG_0001.JPG</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">/path/to/IMG_0001.JPG</span></code></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference external" href="#path-raw">path_raw</a></p></td>
<td><p>None</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">/path/to/IMG_0001.CR2</span></code></p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">/path/to/IMG_0001.CR2</span></code></p></td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="a-name-example-example-a">
<h4><span class="raw-html-m2r"><a name="Example">Example</a></span><a class="headerlink" href="#a-name-example-example-a" title="Link to this heading">¶</a></h4>
<p>To get the path of every raw photo, whether it's a single raw photo or a raw+JPEG pair, one could do something like this:</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">all_raw</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">israw</span> <span class="ow">or</span> <span class="n">p</span><span class="o">.</span><span class="n">has_raw</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">raw</span> <span class="ow">in</span> <span class="n">all_raw</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">path</span> <span class="o">=</span> <span class="n">raw</span><span class="o">.</span><span class="n">path</span> <span class="k">if</span> <span class="n">raw</span><span class="o">.</span><span class="n">israw</span> <span class="k">else</span> <span class="n">raw</span><span class="o">.</span><span class="n">path_raw</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</pre></div>
</div>
</section>
</section>
<section id="a-name-template-system-template-system-a">
<h3><span class="raw-html-m2r"><a name="template-system">Template System</a></span><a class="headerlink" href="#a-name-template-system-template-system-a" title="Link to this heading">¶</a></h3>
<!--[[[cog
from osxphotos.phototemplate import get_template_help
cog.out("\n"+get_template_help())
]]]--><!-- Generated by cog: see phototemplate.cog.md --><p>The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.</p>
<p>In its simplest form, a template statement has the form: <code class="docutils literal notranslate"><span class="pre">&quot;{template_field}&quot;</span></code>, for example <code class="docutils literal notranslate"><span class="pre">&quot;{title}&quot;</span></code> which would resolve to the title of the photo.</p>
<p>Template statements may contain one or more modifiers.  The full syntax is:</p>
<p><code class="docutils literal notranslate"><span class="pre">&quot;pretext{delim+template_field:subfield(field_arg)|filter[find,replace]</span> <span class="pre">conditional&amp;combine_value?bool_value,default}posttext&quot;</span></code></p>
<p>Template statements are white-space sensitive meaning that white space (spaces, tabs) changes the meaning of the template statement.</p>
<p><code class="docutils literal notranslate"><span class="pre">pretext</span></code> and <code class="docutils literal notranslate"><span class="pre">posttext</span></code> are free form text.  For example, if a photo has title &quot;My Photo Title&quot; the template statement <code class="docutils literal notranslate"><span class="pre">&quot;The</span> <span class="pre">title</span> <span class="pre">of</span> <span class="pre">the</span> <span class="pre">photo</span> <span class="pre">is</span> <span class="pre">{title}&quot;</span></code>, resolves to <code class="docutils literal notranslate"><span class="pre">&quot;The</span> <span class="pre">title</span> <span class="pre">of</span> <span class="pre">the</span> <span class="pre">photo</span> <span class="pre">is</span> <span class="pre">My</span> <span class="pre">Photo</span> <span class="pre">Title&quot;</span></code>.  The <code class="docutils literal notranslate"><span class="pre">pretext</span></code> in this example is <code class="docutils literal notranslate"><span class="pre">&quot;The</span> <span class="pre">title</span> <span class="pre">if</span> <span class="pre">the</span> <span class="pre">photo</span> <span class="pre">is</span> <span class="pre">&quot;</span></code> and the template_field is <code class="docutils literal notranslate"><span class="pre">{title}</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">delim</span></code>: optional delimiter string to use when expanding multi-valued template values in-place</p>
<p><code class="docutils literal notranslate"><span class="pre">+</span></code>: If present before template <code class="docutils literal notranslate"><span class="pre">name</span></code>, expands the template in place.  If <code class="docutils literal notranslate"><span class="pre">delim</span></code> not provided, values are joined with no delimiter.</p>
<p>e.g. if Photo keywords are <code class="docutils literal notranslate"><span class="pre">[&quot;foo&quot;,&quot;bar&quot;]</span></code>:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{keyword}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;foo&quot;,</span> <span class="pre">&quot;bar&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{,+keyword}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;foo,bar&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{;</span> <span class="pre">+keyword}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;foo;</span> <span class="pre">bar&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{+keyword}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;foobar&quot;</span></code></p></li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">template_field</span></code>: The template field to resolve.  See <a class="reference external" href="#template-substitutions">Template Substitutions</a> for full list of template fields.</p>
<p><cite>:subfield</cite>: Some templates have sub-fields, For example, <cite>{exiftool:IPTC:Make}`</cite>; the template_field is``exiftool<code class="docutils literal notranslate"><span class="pre">and</span> <span class="pre">the</span> <span class="pre">sub-field</span> <span class="pre">is</span></code>IPTC:Make`.</p>
<p><code class="docutils literal notranslate"><span class="pre">(field_arg)</span></code>: optional arguments to pass to the field; for example, with <code class="docutils literal notranslate"><span class="pre">{folder_album}</span></code> this is used to pass the path separator used for joining folders and albums when rendering the field (default is &quot;/&quot; for <code class="docutils literal notranslate"><span class="pre">{folder_album}</span></code>).</p>
<p><cite>|filter</cite>: You may optionally append one or more filter commands to the end of the template field using the vertical pipe ('|') symbol.  Filters may be combined, separated by '|' as in: <code class="docutils literal notranslate"><span class="pre">{keyword|capitalize|parens}</span></code>.</p>
<p>Valid filters are:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">lower</span></code>: Convert value to lower case, e.g. 'Value' =&gt; 'value'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">upper</span></code>: Convert value to upper case, e.g. 'Value' =&gt; 'VALUE'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">strip</span></code>: Strip whitespace from beginning/end of value, e.g. ' Value ' =&gt; 'Value'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">titlecase</span></code>: Convert value to title case, e.g. 'my value' =&gt; 'My Value'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">capitalize</span></code>: Capitalize first word of value and convert other words to lower case, e.g. 'MY VALUE' =&gt; 'My value'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">braces</span></code>: Enclose value in curly braces, e.g. 'value =&gt; '{value}'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">parens</span></code>: Enclose value in parentheses, e.g. 'value' =&gt; '(value')</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">brackets</span></code>: Enclose value in brackets, e.g. 'value' =&gt; '[value]'</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">shell_quote</span></code>: Quotes the value for safe usage in the shell, e.g. My file.jpeg =&gt; 'My file.jpeg'; only adds quotes if needed.</p></li>
<li><p><cite>function</cite>: Run custom python function to filter value; use in format 'function:/path/to/file.py::function_name'. See example at https://github.com/RhetTbull/osxphotos/blob/master/examples/template_filter.py</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">split(x)</span></code>: Split value into a list of values using x as delimiter, e.g. 'value1;value2' =&gt; ['value1', 'value2'] if used with split(;).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">autosplit</span></code>: Automatically split delimited string into separate values; will split strings delimited by comma, semicolon, or space, e.g. 'value1,value2' =&gt; ['value1', 'value2'].</p></li>
<li><p><cite>chop(x)</cite>: Remove x characters off the end of value, e.g. chop(1): 'Value' =&gt; 'Valu'; when applied to a list, chops characters from each list value, e.g. chop(1): ['travel', 'beach']=&gt; ['trave', 'beac'].</p></li>
<li><p><cite>chomp(x)</cite>: Remove x characters from the beginning of value, e.g. chomp(1): ['Value'] =&gt; ['alue']; when applied to a list, removes characters from each list value, e.g. chomp(1): ['travel', 'beach']=&gt; ['ravel', 'each'].</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sort</span></code>: Sort list of values, e.g. ['c', 'b', 'a'] =&gt; ['a', 'b', 'c'].</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">rsort</span></code>: Sort list of values in reverse order, e.g. ['a', 'b', 'c'] =&gt; ['c', 'b', 'a'].</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">reverse</span></code>: Reverse order of values, e.g. ['a', 'b', 'c'] =&gt; ['c', 'b', 'a'].</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">uniq</span></code>: Remove duplicate values, e.g. ['a', 'b', 'c', 'b', 'a'] =&gt; ['a', 'b', 'c'].</p></li>
<li><p><cite>join(x)</cite>: Join list of values with delimiter x, e.g. join(,): ['a', 'b', 'c'] =&gt; 'a,b,c'; the DELIM option functions similar to join(x) but with DELIM, the join happens before being passed to any filters.May optionally be used without an argument, that is 'join()' which joins values together with no delimiter. e.g. join(): ['a', 'b', 'c'] =&gt; 'abc'.</p></li>
<li><p><cite>append(x)</cite>: Append x to list of values, e.g. append(d): ['a', 'b', 'c'] =&gt; ['a', 'b', 'c', 'd'].</p></li>
<li><p><cite>prepend(x)</cite>: Prepend x to list of values, e.g. prepend(d): ['a', 'b', 'c'] =&gt; ['d', 'a', 'b', 'c'].</p></li>
<li><p><cite>appends(x)</cite>: Append s[tring] Append x to each value of list of values, e.g. appends(d): ['a', 'b', 'c'] =&gt; ['ad', 'bd', 'cd'].</p></li>
<li><p><cite>prepends(x)</cite>: Prepend s[tring] x to each value of list of values, e.g. prepends(d): ['a', 'b', 'c'] =&gt; ['da', 'db', 'dc'].</p></li>
<li><p><cite>remove(x)</cite>: Remove x from list of values, e.g. remove(b): ['a', 'b', 'c'] =&gt; ['a', 'c'].</p></li>
<li><p><cite>slice(start:stop:step)</cite>: Slice list using same semantics as Python's list slicing, e.g. slice(1:3): ['a', 'b', 'c', 'd'] =&gt; ['b', 'c']; slice(1:4:2): ['a', 'b', 'c', 'd'] =&gt; ['b', 'd']; slice(1:): ['a', 'b', 'c', 'd'] =&gt; ['b', 'c', 'd']; slice(:-1): ['a', 'b', 'c', 'd'] =&gt; ['a', 'b', 'c']; slice(::-1): ['a', 'b', 'c', 'd'] =&gt; ['d', 'c', 'b', 'a']. See also sslice().</p></li>
<li><p><cite>sslice(start:stop:step)</cite>: [s(tring) slice] Slice values in a list using same semantics as Python's string slicing, e.g. sslice(1:3):'abcd =&gt; 'bc'; sslice(1:4:2): 'abcd' =&gt; 'bd', etc. See also slice().</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">filter(x)</span></code>: Filter list of values using predicate x; for example, '{folder_album|filter(contains Events)}' returns only folders/albums containing the word 'Events' in their path.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">int</span></code>: Convert values in list to integer, e.g. 1.0 =&gt; 1. If value cannot be converted to integer, remove value from list. ['1.1', 'x'] =&gt; ['1']. See also float.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">float</span></code>: Convert values in list to floating point number, e.g. 1 =&gt; 1.0. If value cannot be converted to float, remove value from list. ['1', 'x'] =&gt; ['1.0']. See also int.</p></li>
</ul>
<p>e.g. if Photo keywords are <code class="docutils literal notranslate"><span class="pre">[&quot;FOO&quot;,&quot;bar&quot;]</span></code>:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{keyword|lower}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;foo&quot;,</span> <span class="pre">&quot;bar&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{keyword|upper}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;FOO&quot;,</span> <span class="pre">&quot;BAR&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{keyword|capitalize}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;Foo&quot;,</span> <span class="pre">&quot;Bar&quot;</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{keyword|lower|parens}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;(foo)&quot;,</span> <span class="pre">&quot;(bar)&quot;</span></code></p></li>
</ul>
<p>e.g. if Photo description is &quot;my description&quot;:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{descr|titlecase}&quot;</span></code> renders to: <code class="docutils literal notranslate"><span class="pre">&quot;My</span> <span class="pre">Description&quot;</span></code></p></li>
</ul>
<p>e.g. If Photo is in <code class="docutils literal notranslate"><span class="pre">Album1</span></code> in <code class="docutils literal notranslate"><span class="pre">Folder1</span></code>:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{folder_album}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">[&quot;Folder1/Album1&quot;]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{folder_album(&gt;)}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">[&quot;Folder1&gt;Album1&quot;]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{folder_album()}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">[&quot;Folder1Album1&quot;]</span></code></p></li>
</ul>
<p><cite>[find,replace]</cite>: optional text replacement to perform on rendered template value.  For example, to replace &quot;/&quot; in an album name, you could use the template <cite>&quot;{album[/,-]}&quot;</cite>.  Multiple replacements can be made by appending &quot;|&quot; and adding another find|replace pair.  e.g. to replace both &quot;/&quot; and &quot;:&quot; in album name: <code class="docutils literal notranslate"><span class="pre">&quot;{album[/,-|:,-]}&quot;</span></code>.  find/replace pairs are not limited to single characters.  The &quot;|&quot; character cannot be used in a find/replace pair.</p>
<p><cite>conditional</cite>: optional conditional expression that is evaluated as boolean (True/False) for use with the <cite>?bool_value</cite> modifier.  Conditional expressions take the form '<cite>not operator value</cite>' where <cite>not</cite> is an optional modifier that negates the <cite>operator</cite>.  Note: the space before the conditional expression is required if you use a conditional expression.  Valid comparison operators are:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">contains</span></code>: template field contains value, similar to python's <code class="docutils literal notranslate"><span class="pre">in</span></code></p></li>
<li><p><cite>matches</cite>: template field contains exactly value, unlike <cite>contains</cite>: does not match partial matches</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">startswith</span></code>: template field starts with value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">endswith</span></code>: template field ends with value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&lt;=</span></code>: template field is less than or equal to value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>: template field is greater than or equal to value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&lt;</span></code>: template field is less than value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&gt;</span></code>: template field is greater than value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">==</span></code>: template field equals value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">!=</span></code>: template field does not equal value</p></li>
</ul>
<p>The <code class="docutils literal notranslate"><span class="pre">value</span></code> part of the conditional expression is treated as a bare (unquoted) word/phrase.  Multiple values may be separated by '|' (the pipe symbol).  <code class="docutils literal notranslate"><span class="pre">value</span></code> is itself a template statement so you can use one or more template fields in <code class="docutils literal notranslate"><span class="pre">value</span></code> which will be resolved before the comparison occurs.</p>
<p>For example:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">{keyword</span> <span class="pre">matches</span> <span class="pre">Beach}</span></code> resolves to True if 'Beach' is a keyword. It would not match keyword 'BeachDay'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">{keyword</span> <span class="pre">contains</span> <span class="pre">Beach}</span></code> resolves to True if any keyword contains the word 'Beach' so it would match both 'Beach' and 'BeachDay'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">{photo.score.overall</span> <span class="pre">&gt;</span> <span class="pre">0.7}</span></code> resolves to True if the photo's overall aesthetic score is greater than 0.7.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">{keyword|lower</span> <span class="pre">contains</span> <span class="pre">beach}</span></code> uses the lower case filter to do case-insensitive matching to match any keyword that contains the word 'beach'.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">{keyword|lower</span> <span class="pre">not</span> <span class="pre">contains</span> <span class="pre">beach}</span></code> uses the <code class="docutils literal notranslate"><span class="pre">not</span></code> modifier to negate the comparison so this resolves to True if there is no keyword that matches 'beach'.</p></li>
</ul>
<p>Examples: to export photos that contain certain keywords with the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span></code> command's <code class="docutils literal notranslate"><span class="pre">--directory</span></code> option:</p>
<p><code class="docutils literal notranslate"><span class="pre">--directory</span> <span class="pre">&quot;{keyword|lower</span> <span class="pre">matches</span> <span class="pre">travel|vacation?Travel-Photos,Not-Travel-Photos}&quot;</span></code></p>
<p>This exports any photo that has keywords 'travel' or 'vacation' into a directory 'Travel-Photos' and all other photos into directory 'Not-Travel-Photos'.</p>
<p>This can be used to rename files as well, for example:
<code class="docutils literal notranslate"><span class="pre">--filename</span> <span class="pre">&quot;{favorite?Favorite-{original_name},{original_name}}&quot;</span></code></p>
<p>This renames any photo that is a favorite as 'Favorite-ImageName.jpg' (where 'ImageName.jpg' is the original name of the photo) and all other photos with the unmodified original name.</p>
<p><cite>&amp;combine_value</cite>: Template fields may be combined with another template statement to return multiple values. The combine_value is another template statement. For example, the template {created.year&amp;{folder_album,}} would resolve to [&quot;1999&quot;, &quot;Vacation&quot;] if the photo was created in 1999 and was in the album Vacation. Because the combine_value is a template statement, multiple templates may be combined together by nesting the combine operator: {template1&amp;{template2&amp;{template3,},},}. In this example, a null default value is used to prevent the default value from being combined if any of the nested templates does not resolve to a value</p>
<p><code class="docutils literal notranslate"><span class="pre">?bool_value</span></code>: Template fields may be evaluated as boolean (True/False) by appending &quot;?&quot; after the field name (and following &quot;(field_arg)&quot; or &quot;[find/replace]&quot;.  If a field is True (e.g. photo is HDR and field is <code class="docutils literal notranslate"><span class="pre">&quot;{hdr}&quot;</span></code>) or has any value, the value following the &quot;?&quot; will be used to render the template instead of the actual field value.  If the template field evaluates to False (e.g. in above example, photo is not HDR) or has no value (e.g. photo has no title and field is <code class="docutils literal notranslate"><span class="pre">&quot;{title}&quot;</span></code>) then the default value following a &quot;,&quot; will be used.</p>
<p>e.g. if photo is an HDR image,</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{hdr?ISHDR,NOTHDR}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;ISHDR&quot;</span></code></p></li>
</ul>
<p>and if it is not an HDR image,</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{hdr?ISHDR,NOTHDR}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;NOTHDR&quot;</span></code></p></li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">,default</span></code>: optional default value to use if the template name has no value.  This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like <code class="docutils literal notranslate"><span class="pre">{created.strftime}</span></code>.  If no default value provided, &quot;_&quot; is used.</p>
<p>e.g., if photo has no title set,</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{title}&quot;</span></code> renders to &quot;_&quot;</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{title,I</span> <span class="pre">have</span> <span class="pre">no</span> <span class="pre">title}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;I</span> <span class="pre">have</span> <span class="pre">no</span> <span class="pre">title&quot;</span></code></p></li>
</ul>
<p>Template fields such as <code class="docutils literal notranslate"><span class="pre">created.strftime</span></code> use the default value to pass the template to use for <code class="docutils literal notranslate"><span class="pre">strftime</span></code>.</p>
<p>e.g., if photo date is 4 February 2020, 19:07:38,</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;{created.strftime,%Y-%m-%d-%H%M%S}&quot;</span></code> renders to <code class="docutils literal notranslate"><span class="pre">&quot;2020-02-04-190738&quot;</span></code></p></li>
</ul>
<p>Some template fields such as <code class="docutils literal notranslate"><span class="pre">&quot;{media_type}&quot;</span></code> use the default value to allow customization of the output. For example, <code class="docutils literal notranslate"><span class="pre">&quot;{media_type}&quot;</span></code> resolves to the special media type of the photo such as <code class="docutils literal notranslate"><span class="pre">panorama</span></code> or <code class="docutils literal notranslate"><span class="pre">selfie</span></code>.  You may use the default value to override these in form: <code class="docutils literal notranslate"><span class="pre">&quot;{media_type,video=vidéo;time_lapse=vidéo_accélérée}&quot;</span></code>. In this example, if photo was a time_lapse photo, <code class="docutils literal notranslate"><span class="pre">media_type</span></code> would resolve to <code class="docutils literal notranslate"><span class="pre">vidéo_accélérée</span></code> instead of <code class="docutils literal notranslate"><span class="pre">time_lapse</span></code>.</p>
<p>Either or both bool_value or default (False value) may be empty which would result in empty string <code class="docutils literal notranslate"><span class="pre">&quot;&quot;</span></code> when rendered.</p>
<p>If you want to include &quot;{&quot; or &quot;}&quot; in the output, use &quot;{openbrace}&quot; or &quot;{closebrace}&quot; template substitution.</p>
<p>e.g. <code class="docutils literal notranslate"><span class="pre">&quot;{created.year}/{openbrace}{title}{closebrace}&quot;</span></code> would result in <code class="docutils literal notranslate"><span class="pre">&quot;2020/{Photo</span> <span class="pre">Title}&quot;</span></code>.</p>
<p><strong>Variables</strong></p>
<p>You can define variables for later use in the template string using the format <code class="docutils literal notranslate"><span class="pre">{var:NAME,VALUE}</span></code> where <code class="docutils literal notranslate"><span class="pre">VALUE</span></code> is a template statement.  Variables may then be referenced using the format <code class="docutils literal notranslate"><span class="pre">%NAME</span></code>. For example: <code class="docutils literal notranslate"><span class="pre">{var:foo,bar}</span></code> defines the variable <code class="docutils literal notranslate"><span class="pre">%foo</span></code> to have value <code class="docutils literal notranslate"><span class="pre">bar</span></code>. This can be useful if you want to re-use a complex template value in multiple places within your template string or for allowing the use of characters that would otherwise be prohibited in a template string. For example, the &quot;pipe&quot; (<code class="docutils literal notranslate"><span class="pre">|</span></code>) character is not allowed in a find/replace pair but you can get around this limitation like so: <code class="docutils literal notranslate"><span class="pre">{var:pipe,{pipe}}{title[-,%pipe]}</span></code> which replaces the <code class="docutils literal notranslate"><span class="pre">-</span></code> character with <code class="docutils literal notranslate"><span class="pre">|</span></code> (the value of <code class="docutils literal notranslate"><span class="pre">%pipe</span></code>).</p>
<p>Another use case for variables is filtering combined template values. For example, using the <code class="docutils literal notranslate"><span class="pre">&amp;combine_value</span></code> mechanism to combine two template values that might result in duplicate values, you could do the following: <code class="docutils literal notranslate"><span class="pre">{var:myvar,{template1&amp;{template2,},}}{%myvar|uniq}</span></code> which allows the use of the uniq filter against the combined template values.</p>
<p>Variables can also be referenced as fields in the template string, for example: <code class="docutils literal notranslate"><span class="pre">{var:year,{created.year}}{original_name}-{%year}</span></code>. In some cases, use of variables can make your template string more readable.  Variables can be used as template fields, as values for filters, as values for conditional operations, or as default values.  When used as a conditional value or default value, variables should be treated like any other field and enclosed in braces as conditional and default values are evaluated as template strings. For example: <code class="docutils literal notranslate"><span class="pre">{var:name,Katie}{person</span> <span class="pre">contains</span> <span class="pre">{%name}?{%name},Not-{%name}}</span></code>.</p>
<p>If you need to use a <code class="docutils literal notranslate"><span class="pre">%</span></code> (percent sign character), you can escape the percent sign by using <code class="docutils literal notranslate"><span class="pre">%%</span></code>.  You can also use the <code class="docutils literal notranslate"><span class="pre">{percent}</span></code> template field where a template field is required. For example:</p>
<p><code class="docutils literal notranslate"><span class="pre">{title[:,%%]}</span></code> replaces the <code class="docutils literal notranslate"><span class="pre">:</span></code> with <code class="docutils literal notranslate"><span class="pre">%</span></code> and <code class="docutils literal notranslate"><span class="pre">{title</span> <span class="pre">contains</span> <span class="pre">Foo?{title}{percent},{title}}</span></code> adds <code class="docutils literal notranslate"><span class="pre">%</span></code> to the  title if it contains <code class="docutils literal notranslate"><span class="pre">Foo</span></code>.
<span class="raw-html-m2r"><!--[[[end]]] --></span></p>
<p>The following template field substitutions are availabe for use the templating system.</p>
<!--[[[cog
from osxphotos.phototemplate import get_template_field_table
cog.out("\n"+get_template_field_table()+"\n")
]]]--><div class="table-wrapper docutils container">
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>Field</p></th>
<th class="head"><p>Description</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>{name}</p></td>
<td><p>Current filename of the photo</p></td>
</tr>
<tr class="row-odd"><td><p>{original_name}</p></td>
<td><p>Photo's original filename when imported to Photos</p></td>
</tr>
<tr class="row-even"><td><p>{title}</p></td>
<td><p>Title of the photo</p></td>
</tr>
<tr class="row-odd"><td><p>{descr}</p></td>
<td><p>Description of the photo</p></td>
</tr>
<tr class="row-even"><td><p>{media_type}</p></td>
<td><p>Special media type resolved in this precedence: selfie, time_lapse, panorama, slow_mo, screenshot, screen_recording, portrait, live_photo, burst, photo, video. Defaults to 'photo' or 'video' if no special type. Customize one or more media types using format: '{media_type,video=vidéo;time_lapse=vidéo_accélérée}'</p></td>
</tr>
<tr class="row-odd"><td><p>{photo_or_video}</p></td>
<td><p>'photo' or 'video' depending on what type the image is. To customize, use default value as in '{photo_or_video,photo=fotos;video=videos}'</p></td>
</tr>
<tr class="row-even"><td><p>{hdr}</p></td>
<td><p>Photo is HDR?; True/False value, use in format '{hdr?VALUE_IF_TRUE,VALUE_IF_FALSE}'</p></td>
</tr>
<tr class="row-odd"><td><p>{edited}</p></td>
<td><p>True if photo has been edited (has adjustments), otherwise False; use in format '{edited?VALUE_IF_TRUE,VALUE_IF_FALSE}'</p></td>
</tr>
<tr class="row-even"><td><p>{edited_version}</p></td>
<td><p>True if template is being rendered for the edited version of a photo, otherwise False.</p></td>
</tr>
<tr class="row-odd"><td><p>{favorite}</p></td>
<td><p>Photo has been marked as favorite?; True/False value, use in format '{favorite?VALUE_IF_TRUE,VALUE_IF_FALSE}'</p></td>
</tr>
<tr class="row-even"><td><p>{created}</p></td>
<td><p>Photo's creation date in ISO format, e.g. '2020-03-22'</p></td>
</tr>
<tr class="row-odd"><td><p>{created.date}</p></td>
<td><p>Photo's creation date in ISO format, e.g. '2020-03-22'</p></td>
</tr>
<tr class="row-even"><td><p>{created.year}</p></td>
<td><p>4-digit year of photo creation time</p></td>
</tr>
<tr class="row-odd"><td><p>{created.yy}</p></td>
<td><p>2-digit year of photo creation time</p></td>
</tr>
<tr class="row-even"><td><p>{created.mm}</p></td>
<td><p>2-digit month of the photo creation time (zero padded)</p></td>
</tr>
<tr class="row-odd"><td><p>{created.month}</p></td>
<td><p>Month name in user's locale of the photo creation time</p></td>
</tr>
<tr class="row-even"><td><p>{created.mon}</p></td>
<td><p>Month abbreviation in the user's locale of the photo creation time</p></td>
</tr>
<tr class="row-odd"><td><p>{created.dd}</p></td>
<td><p>2-digit day of the month (zero padded) of photo creation time</p></td>
</tr>
<tr class="row-even"><td><p>{created.dow}</p></td>
<td><p>Day of week in user's locale of the photo creation time</p></td>
</tr>
<tr class="row-odd"><td><p>{created.doy}</p></td>
<td><p>3-digit day of year (e.g Julian day) of photo creation time, starting from 1 (zero padded)</p></td>
</tr>
<tr class="row-even"><td><p>{created.hour}</p></td>
<td><p>2-digit hour of the photo creation time</p></td>
</tr>
<tr class="row-odd"><td><p>{created.min}</p></td>
<td><p>2-digit minute of the photo creation time</p></td>
</tr>
<tr class="row-even"><td><p>{created.sec}</p></td>
<td><p>2-digit second of the photo creation time</p></td>
</tr>
<tr class="row-odd"><td><p>{created.strftime}</p></td>
<td><p>Apply strftime template to file creation date/time. Should be used in form {created.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {created.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. See <a class="reference external" href="https://strftime.org/">https://strftime.org/</a> for help on strftime templates.</p></td>
</tr>
<tr class="row-even"><td><p>{modified}</p></td>
<td><p>Photo's modification date in ISO format, e.g. '2020-03-22'; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.date}</p></td>
<td><p>Photo's modification date in ISO format, e.g. '2020-03-22'; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.year}</p></td>
<td><p>4-digit year of photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.yy}</p></td>
<td><p>2-digit year of photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.mm}</p></td>
<td><p>2-digit month of the photo modification time (zero padded); uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.month}</p></td>
<td><p>Month name in user's locale of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.mon}</p></td>
<td><p>Month abbreviation in the user's locale of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.dd}</p></td>
<td><p>2-digit day of the month (zero padded) of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.dow}</p></td>
<td><p>Day of week in user's locale of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.doy}</p></td>
<td><p>3-digit day of year (e.g Julian day) of photo modification time, starting from 1 (zero padded); uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.hour}</p></td>
<td><p>2-digit hour of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.min}</p></td>
<td><p>2-digit minute of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-even"><td><p>{modified.sec}</p></td>
<td><p>2-digit second of the photo modification time; uses creation date if photo is not modified</p></td>
</tr>
<tr class="row-odd"><td><p>{modified.strftime}</p></td>
<td><p>Apply strftime template to file modification date/time. Should be used in form {modified.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {modified.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. Uses creation date if photo is not modified. See <a class="reference external" href="https://strftime.org/">https://strftime.org/</a> for help on strftime templates.</p></td>
</tr>
<tr class="row-even"><td><p>{today}</p></td>
<td><p>Current date in iso format, e.g. '2020-03-22'</p></td>
</tr>
<tr class="row-odd"><td><p>{today.date}</p></td>
<td><p>Current date in iso format, e.g. '2020-03-22'</p></td>
</tr>
<tr class="row-even"><td><p>{today.year}</p></td>
<td><p>4-digit year of current date</p></td>
</tr>
<tr class="row-odd"><td><p>{today.yy}</p></td>
<td><p>2-digit year of current date</p></td>
</tr>
<tr class="row-even"><td><p>{today.mm}</p></td>
<td><p>2-digit month of the current date (zero padded)</p></td>
</tr>
<tr class="row-odd"><td><p>{today.month}</p></td>
<td><p>Month name in user's locale of the current date</p></td>
</tr>
<tr class="row-even"><td><p>{today.mon}</p></td>
<td><p>Month abbreviation in the user's locale of the current date</p></td>
</tr>
<tr class="row-odd"><td><p>{today.dd}</p></td>
<td><p>2-digit day of the month (zero padded) of current date</p></td>
</tr>
<tr class="row-even"><td><p>{today.dow}</p></td>
<td><p>Day of week in user's locale of the current date</p></td>
</tr>
<tr class="row-odd"><td><p>{today.doy}</p></td>
<td><p>3-digit day of year (e.g Julian day) of current date, starting from 1 (zero padded)</p></td>
</tr>
<tr class="row-even"><td><p>{today.hour}</p></td>
<td><p>2-digit hour of the current date</p></td>
</tr>
<tr class="row-odd"><td><p>{today.min}</p></td>
<td><p>2-digit minute of the current date</p></td>
</tr>
<tr class="row-even"><td><p>{today.sec}</p></td>
<td><p>2-digit second of the current date</p></td>
</tr>
<tr class="row-odd"><td><p>{today.strftime}</p></td>
<td><p>Apply strftime template to current date/time. Should be used in form {today.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {today.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. See <a class="reference external" href="https://strftime.org/">https://strftime.org/</a> for help on strftime templates.</p></td>
</tr>
<tr class="row-even"><td><p>{place.name}</p></td>
<td><p>Place name from the photo's reverse geolocation data, as displayed in Photos</p></td>
</tr>
<tr class="row-odd"><td><p>{place.country_code}</p></td>
<td><p>The ISO country code from the photo's reverse geolocation data</p></td>
</tr>
<tr class="row-even"><td><p>{place.name.country}</p></td>
<td><p>Country name from the photo's reverse geolocation data</p></td>
</tr>
<tr class="row-odd"><td><p>{place.name.state_province}</p></td>
<td><p>State or province name from the photo's reverse geolocation data</p></td>
</tr>
<tr class="row-even"><td><p>{place.name.city}</p></td>
<td><p>City or locality name from the photo's reverse geolocation data</p></td>
</tr>
<tr class="row-odd"><td><p>{place.name.area_of_interest}</p></td>
<td><p>Area of interest name (e.g. landmark or public place) from the photo's reverse geolocation data</p></td>
</tr>
<tr class="row-even"><td><p>{place.address}</p></td>
<td><p>Postal address from the photo's reverse geolocation data, e.g. '2007 18th St NW, Washington, DC 20009, United States'</p></td>
</tr>
<tr class="row-odd"><td><p>{place.address.street}</p></td>
<td><p>Street part of the postal address, e.g. '2007 18th St NW'</p></td>
</tr>
<tr class="row-even"><td><p>{place.address.city}</p></td>
<td><p>City part of the postal address, e.g. 'Washington'</p></td>
</tr>
<tr class="row-odd"><td><p>{place.address.state_province}</p></td>
<td><p>State/province part of the postal address, e.g. 'DC'</p></td>
</tr>
<tr class="row-even"><td><p>{place.address.postal_code}</p></td>
<td><p>Postal code part of the postal address, e.g. '20009'</p></td>
</tr>
<tr class="row-odd"><td><p>{place.address.country}</p></td>
<td><p>Country name of the postal address, e.g. 'United States'</p></td>
</tr>
<tr class="row-even"><td><p>{place.address.country_code}</p></td>
<td><p>ISO country code of the postal address, e.g. 'US'</p></td>
</tr>
<tr class="row-odd"><td><p>{searchinfo.season}</p></td>
<td><p>Season of the year associated with a photo, e.g. 'Summer'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).</p></td>
</tr>
<tr class="row-even"><td><p>{exif.camera_make}</p></td>
<td><p>Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'</p></td>
</tr>
<tr class="row-odd"><td><p>{exif.camera_model}</p></td>
<td><p>Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'</p></td>
</tr>
<tr class="row-even"><td><p>{exif.lens_model}</p></td>
<td><p>Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'</p></td>
</tr>
<tr class="row-odd"><td><p>{moment}</p></td>
<td><p>The moment title of the photo</p></td>
</tr>
<tr class="row-even"><td><p>{uuid}</p></td>
<td><p>Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'</p></td>
</tr>
<tr class="row-odd"><td><p>{shortuuid}</p></td>
<td><p>A shorter representation of photo's internal universally unique identifier (UUID) for the photo, a 22-character string unique to the photo, e.g. 'JYsxugP9UjetmCbBCHXcmu'</p></td>
</tr>
<tr class="row-even"><td><p>{id}</p></td>
<td><p>A unique number for the photo based on its primary key in the Photos database. A sequential integer, e.g. 1, 2, 3...etc.  Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{id:05d}' which results in 00001, 00002, 00003...etc.</p></td>
</tr>
<tr class="row-odd"><td><p>{counter}</p></td>
<td><p>A sequential counter, starting at 0, that increments each time it is evaluated.To start counting at a value other than 0, append append '(starting_value)' to the field name.For example, to start counting at 1 instead of 0: '{counter(1)}'.May be formatted using a python string format code.For example, to format as a 5-digit integer and pad with zeros, use '{counter:05d(1)}'which results in 00001, 00002, 00003...etc.You may also specify a stop value which causes the counter to reset to the starting valuewhen the stop value is reached and a step size which causes the counter to increment bythe specified value instead of 1. Use the format '{counter(start,stop,step)}' where start,stop, and step are integers. For example, to count from 1 to 10 by 2, use '{counter(1,11,2)}'.Note that the counter stops counting when the stop value is reached and does not return thestop value. Start, stop, and step are optional and may be omitted. For example, to countfrom 0 by 2s, use '{counter(,,2)}'.You may create an arbitrary number of counters by appending a unique name to the field namepreceded by a period: '{counter.a}', '{counter.b}', etc. Each counter will have its own stateand will start at 0 and increment by 1 unless otherwise specified. Note: {counter} is not suitable for use with 'export' and '--update' as the counter associated with a photo may change between export sessions. See also {id}.</p></td>
</tr>
<tr class="row-even"><td><p>{album_seq}</p></td>
<td><p>An integer, starting at 0, indicating the photo's index (sequence) in the containing album. Only valid when used in a '--filename' template and only when '{album}' or '{folder_album}' is used in the '--directory' template. For example '--directory &quot;{folder_album}&quot; --filename &quot;{album<em>seq}</em>{original_name}&quot;'. To start counting at a value other than 0, append append '(starting_value)' to the field name.  For example, to start counting at 1 instead of 0: '{album_seq(1)}'. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{album_seq:05d}' which results in 00000, 00001, 00002...etc. To format while also using a starting value: '{album_seq:05d(1)}' which results in 0001, 00002...etc.This may result in incorrect sequences if you have duplicate albums with the same name; see also '{folder_album_seq}'.</p></td>
</tr>
<tr class="row-odd"><td><p>{folder_album_seq}</p></td>
<td><p>An integer, starting at 0, indicating the photo's index (sequence) in the containing album and folder path. Only valid when used in a '--filename' template and only when '{folder_album}' is used in the '--directory' template. For example '--directory &quot;{folder_album}&quot; --filename &quot;{folder_album<em>seq}</em>{original_name}&quot;'. To start counting at a value other than 0, append '(starting_value)' to the field name. For example, to start counting at 1 instead of 0: '{folder_album_seq(1)}' May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{folder_album_seq:05d}' which results in 00000, 00001, 00002...etc. To format while also using a starting value: '{folder_album_seq:05d(1)}' which results in 0001, 00002...etc.This may result in incorrect sequences if you have duplicate albums with the same name in the same folder; see also '{album_seq}'.</p></td>
</tr>
<tr class="row-even"><td><p>{comma}</p></td>
<td><p>A comma: ','</p></td>
</tr>
<tr class="row-odd"><td><p>{semicolon}</p></td>
<td><p>A semicolon: ';'</p></td>
</tr>
<tr class="row-even"><td><p>{questionmark}</p></td>
<td><p>A question mark: '?'</p></td>
</tr>
<tr class="row-odd"><td><p>{pipe}</p></td>
<td><p>A vertical pipe: '|'</p></td>
</tr>
<tr class="row-even"><td><p>{percent}</p></td>
<td><p>A percent sign: '%'</p></td>
</tr>
<tr class="row-odd"><td><p>{ampersand}</p></td>
<td><p>an ampersand symbol: '&amp;'</p></td>
</tr>
<tr class="row-even"><td><p>{openbrace}</p></td>
<td><p>An open brace: '{'</p></td>
</tr>
<tr class="row-odd"><td><p>{closebrace}</p></td>
<td><p>A close brace: '}'</p></td>
</tr>
<tr class="row-even"><td><p>{openparens}</p></td>
<td><p>An open parentheses: '('</p></td>
</tr>
<tr class="row-odd"><td><p>{closeparens}</p></td>
<td><p>A close parentheses: ')'</p></td>
</tr>
<tr class="row-even"><td><p>{openbracket}</p></td>
<td><p>An open bracket: '['</p></td>
</tr>
<tr class="row-odd"><td><p>{closebracket}</p></td>
<td><p>A close bracket: ']'</p></td>
</tr>
<tr class="row-even"><td><p>{newline}</p></td>
<td><p>A newline: 'n'</p></td>
</tr>
<tr class="row-odd"><td><p>{lf}</p></td>
<td><p>A line feed: 'n', alias for {newline}</p></td>
</tr>
<tr class="row-even"><td><p>{cr}</p></td>
<td><p>A carriage return: 'r'</p></td>
</tr>
<tr class="row-odd"><td><p>{crlf}</p></td>
<td><p>A carriage return + line feed: 'rn'</p></td>
</tr>
<tr class="row-even"><td><p>{tab}</p></td>
<td><dl class="field-list simple">
<dt class="field-odd">A tab<span class="colon">:</span></dt>
<dd class="field-odd"><p>'t'</p>
</dd>
</dl>
</td>
</tr>
<tr class="row-odd"><td><p>{osxphotos_version}</p></td>
<td><p>The osxphotos version, e.g. '0.74.2'</p></td>
</tr>
<tr class="row-even"><td><p>{osxphotos_cmd_line}</p></td>
<td><p>The full command line used to run osxphotos</p></td>
</tr>
<tr class="row-odd"><td><p>{album}</p></td>
<td><p>Album(s) photo is contained in</p></td>
</tr>
<tr class="row-even"><td><p>{folder_album}</p></td>
<td><p>Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder</p></td>
</tr>
<tr class="row-odd"><td><p>{project}</p></td>
<td><p>Project(s) photo is contained in (such as greeting cards, calendars, slideshows)</p></td>
</tr>
<tr class="row-even"><td><p>{album_project}</p></td>
<td><p>Album(s) and project(s) photo is contained in; treats projects as regular albums</p></td>
</tr>
<tr class="row-odd"><td><p>{folder_album_project}</p></td>
<td><p>Folder path + album (includes projects as albums) photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder</p></td>
</tr>
<tr class="row-even"><td><p>{keyword}</p></td>
<td><p>Keyword(s) assigned to photo</p></td>
</tr>
<tr class="row-odd"><td><p>{person}</p></td>
<td><p>Person(s) / face(s) in a photo</p></td>
</tr>
<tr class="row-even"><td><p>{label}</p></td>
<td><p>Image categorization label associated with a photo (Photos 5+ only). Labels are added automatically by Photos using machine learning algorithms to categorize images. These are not the same as {keyword} which refers to the user-defined keywords/tags applied in Photos.</p></td>
</tr>
<tr class="row-odd"><td><p>{label_normalized}</p></td>
<td><p>All lower case version of 'label' (Photos 5+ only)</p></td>
</tr>
<tr class="row-even"><td><p>{comment}</p></td>
<td><p>Comment(s) on shared Photos; format is 'Person name: comment text' (Photos 5+ only)</p></td>
</tr>
<tr class="row-odd"><td><p>{exiftool}</p></td>
<td><p>Format: '{exiftool:GROUP:TAGNAME}'; use exiftool (https://exiftool.org) to extract metadata, in form GROUP:TAGNAME, from image.  E.g. '{exiftool:EXIF:Make}' to get camera make, or {exiftool:IPTC:Keywords} to extract keywords. See https://exiftool.org/TagNames/ for list of valid tag names.  You must specify group (e.g. EXIF, IPTC, etc) as used in 'exiftool -G'. exiftool must be installed in the path to use this template.</p></td>
</tr>
<tr class="row-even"><td><p>{searchinfo.holiday}</p></td>
<td><p>Holiday names associated with a photo, e.g. 'Christmas Day'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).</p></td>
</tr>
<tr class="row-odd"><td><p>{searchinfo.activity}</p></td>
<td><p>Activities associated with a photo, e.g. 'Sporting Event'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).</p></td>
</tr>
<tr class="row-even"><td><p>{searchinfo.venue}</p></td>
<td><p>Venues associated with a photo, e.g. name of restaurant; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).</p></td>
</tr>
<tr class="row-odd"><td><p>{searchinfo.venue_type}</p></td>
<td><p>Venue types associated with a photo, e.g. 'Restaurant'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).</p></td>
</tr>
<tr class="row-even"><td><p>{photo}</p></td>
<td><p>Provides direct access to the PhotoInfo object for the photo. Must be used in format '{photo.property}' where 'property' represents a PhotoInfo property. For example: '{photo.favorite}' is the same as '{favorite}' and '{photo.place.name}' is the same as '{place.name}'. '{photo}' provides access to properties that are not available as separate template fields but it assumes some knowledge of the underlying PhotoInfo class.  See <a class="reference external" href="https://rhettbull.github.io/osxphotos/">https://rhettbull.github.io/osxphotos/</a> for additional documentation on the PhotoInfo class.</p></td>
</tr>
<tr class="row-odd"><td><p>{detected_text}</p></td>
<td><p>List of text strings found in the image after performing text detection. Using '{detected_text}' will cause osxphotos to perform text detection on your photos using the built-in macOS text detection algorithms which will slow down your export. The results for each photo will be cached in the export database so that future exports with '--update' do not need to reprocess each photo. You may pass a confidence threshold value between 0.0 and 1.0 after a colon as in '{detected_text:0.5}'; The default confidence threshold is 0.75. '{detected_text}' works only on macOS Catalina (10.15) or later. Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.</p></td>
</tr>
<tr class="row-even"><td><p>{shell_quote}</p></td>
<td><p>Use in form '{shell_quote,TEMPLATE}'; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg =&gt; 'My file.jpeg'; only adds quotes if needed.</p></td>
</tr>
<tr class="row-odd"><td><p>{strip}</p></td>
<td><p>Use in form '{strip,TEMPLATE}'; strips whitespace from begining and end of rendered TEMPLATE value(s).</p></td>
</tr>
<tr class="row-even"><td><p>{format}</p></td>
<td><p>Use in form '{format:TYPE:FORMAT,TEMPLATE}'; converts TEMPLATE value to TYPE then formats the value using Python string formatting codes specified by FORMAT; TYPE is one of: 'int', 'float', or 'str'. For example, '{format:float:.1f,{exiftool:EXIF:FocalLength}}' will format focal length to 1 decimal place (e.g. '100.0').</p></td>
</tr>
<tr class="row-odd"><td><p>{function}</p></td>
<td><p>Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where 'file.py' is the path/name of the python file and 'function_name' is the name of the function to call. The file name may also be url to a python file, e.g. '{function:https://raw.githubusercontent.com/RhetTbull/osxphotos/main/examples/template_function.py::example}'. The function will be passed the PhotoInfo object for the photo. See https://github.com/RhetTbull/osxphotos/blob/master/examples/template_function.py for an example of how to implement a template function.</p></td>
</tr>
</tbody>
</table>
</div>
<!--[[[end]]] --></section>
<section id="a-name-exiftool-exiftool-a">
<h3><span class="raw-html-m2r"><a name="exiftool">ExifTool</a></span><a class="headerlink" href="#a-name-exiftool-exiftool-a" title="Link to this heading">¶</a></h3>
<p>osxphotos includes its own <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> library that can be accessed via <code class="docutils literal notranslate"><span class="pre">osxphotos.exiftool</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.exiftool</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExifTool</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exiftool</span> <span class="o">=</span> <span class="n">ExifTool</span><span class="p">(</span><span class="s2">&quot;/Users/rhet/Downloads/test.jpeg&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exifdict</span> <span class="o">=</span> <span class="n">exiftool</span><span class="o">.</span><span class="n">asdict</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exifdict</span><span class="p">[</span><span class="s2">&quot;EXIF:Make&quot;</span><span class="p">]</span>
<span class="go">&#39;Canon&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exiftool</span><span class="o">.</span><span class="n">setvalue</span><span class="p">(</span><span class="s2">&quot;IPTC:Keywords&quot;</span><span class="p">,</span><span class="s2">&quot;Keyword1&quot;</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exiftool</span><span class="o">.</span><span class="n">asdict</span><span class="p">()[</span><span class="s2">&quot;IPTC:Keywords&quot;</span><span class="p">]</span>
<span class="go">&#39;Keyword1&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exiftool</span><span class="o">.</span><span class="n">addvalues</span><span class="p">(</span><span class="s2">&quot;IPTC:Keywords&quot;</span><span class="p">,</span><span class="s2">&quot;Keyword2&quot;</span><span class="p">,</span><span class="s2">&quot;Keyword3&quot;</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">exiftool</span><span class="o">.</span><span class="n">asdict</span><span class="p">()[</span><span class="s2">&quot;IPTC:Keywords&quot;</span><span class="p">]</span>
<span class="go">[&#39;Keyword1&#39;, &#39;Keyword2&#39;, &#39;Keyword3&#39;]</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">ExifTool(filepath,</span> <span class="pre">exiftool=None,</span> <span class="pre">large_file_support=True)</span></code></p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">filepath</span></code>: str, path to photo</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">exiftool</span></code>: str, optional path to <code class="docutils literal notranslate"><span class="pre">exiftool</span></code>; if not provided, will look for <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> in the system path</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">large_file_support</span></code>: bool, if True, enables large file support in exiftool (<code class="docutils literal notranslate"><span class="pre">-api</span> <span class="pre">largefilesupport=1</span></code>)</p></li>
</ul>
<section id="exiftool-methods">
<h4>ExifTool methods<a class="headerlink" href="#exiftool-methods" title="Link to this heading">¶</a></h4>
<ul class="simple">
<li><p><cite>asdict(tag_groups=True)</cite>: returns all EXIF metadata found in the file as a dictionary in following form (Note: this shows just a subset of available metadata).  See <a class="reference external" href="https://exiftool.org/">exiftool</a> documentation to understand which metadata keys are available. If <code class="docutils literal notranslate"><span class="pre">tag_groups</span></code> is True (default) dict keys are in form &quot;GROUP:TAG&quot;, e.g. &quot;IPTC:Keywords&quot;. If <code class="docutils literal notranslate"><span class="pre">tag_groups</span></code> is False, dict keys do not have group names, e.g. &quot;Keywords&quot;.</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">&#39;Composite:Aperture&#39;</span><span class="p">:</span> <span class="mf">2.2</span><span class="p">,</span>
 <span class="s1">&#39;Composite:GPSPosition&#39;</span><span class="p">:</span> <span class="s1">&#39;-34.9188916666667 138.596861111111&#39;</span><span class="p">,</span>
 <span class="s1">&#39;Composite:ImageSize&#39;</span><span class="p">:</span> <span class="s1">&#39;2754 2754&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:CreateDate&#39;</span><span class="p">:</span> <span class="s1">&#39;2017:06:20 17:18:56&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:LensMake&#39;</span><span class="p">:</span> <span class="s1">&#39;Apple&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:LensModel&#39;</span><span class="p">:</span> <span class="s1">&#39;iPhone 6s back camera 4.15mm f/2.2&#39;</span><span class="p">,</span>
 <span class="s1">&#39;EXIF:Make&#39;</span><span class="p">:</span> <span class="s1">&#39;Apple&#39;</span><span class="p">,</span>
 <span class="s1">&#39;XMP:Title&#39;</span><span class="p">:</span> <span class="s1">&#39;Elder Park&#39;</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
</div>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">json()</span></code>: returns same information as <code class="docutils literal notranslate"><span class="pre">asdict()</span></code> but as a serialized JSON string.</p></li>
<li><p><cite>setvalue(tag, value)</cite>: write to the EXIF data in the photo file. To delete a tag, use setvalue with value = <cite>None</cite>. For example:</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">photo</span><span class="o">.</span><span class="n">exiftool</span><span class="o">.</span><span class="n">setvalue</span><span class="p">(</span><span class="s2">&quot;XMP:Title&quot;</span><span class="p">,</span> <span class="s2">&quot;Title of photo&quot;</span><span class="p">)</span>
</pre></div>
</div>
<ul class="simple">
<li><p><cite>addvalues(tag, *values)</cite>: Add one or more value(s) to tag.  For a tag that accepts multiple values, like &quot;IPTC:Keywords&quot;, this will add the values as additional list values.  However, for tags which are not usually lists, such as &quot;EXIF:ISO&quot; this will literally add the new value to the old value which is probably not the desired effect.  Be sure you understand the behavior of the individual tag before using this. For example:</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">photo</span><span class="o">.</span><span class="n">exiftool</span><span class="o">.</span><span class="n">addvalues</span><span class="p">(</span><span class="s2">&quot;IPTC:Keywords&quot;</span><span class="p">,</span> <span class="s2">&quot;vacation&quot;</span><span class="p">,</span> <span class="s2">&quot;beach&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>osxphotos.exiftool also provides an <code class="docutils literal notranslate"><span class="pre">ExifToolCaching</span></code> class which caches all metadata after the first call to <code class="docutils literal notranslate"><span class="pre">exiftool</span></code>. This can significantly speed up repeated access to the metadata but should only be used if you do not intend to modify the file's metadata.</p>
<p><cite>``PhotoInfo.exiftool`</cite> &lt;#photoinfo-exiftool&gt;`_ returns an <code class="docutils literal notranslate"><span class="pre">ExifToolCaching</span></code> instance for the original image in the Photos library.</p>
</section>
<section id="implementation-note">
<h4>Implementation Note<a class="headerlink" href="#implementation-note" title="Link to this heading">¶</a></h4>
<p><code class="docutils literal notranslate"><span class="pre">ExifTool()</span></code> runs <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> as a subprocess using the <code class="docutils literal notranslate"><span class="pre">-stay_open</span> <span class="pre">True</span></code> flag to keep the process running in the background.  The subprocess will be cleaned up when your main script terminates.  <code class="docutils literal notranslate"><span class="pre">ExifTool()</span></code> uses a singleton pattern to ensure that only one instance of <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> is created.  Multiple instances of <code class="docutils literal notranslate"><span class="pre">ExifTool()</span></code> will all use the same <code class="docutils literal notranslate"><span class="pre">exiftool</span></code> subprocess.</p>
</section>
</section>
<section id="a-name-photoexporter-photoexporter-a">
<h3><span class="raw-html-m2r"><a name="photoexporter">PhotoExporter</a></span><a class="headerlink" href="#a-name-photoexporter-photoexporter-a" title="Link to this heading">¶</a></h3>
<p><a class="reference external" href="#photoinfo-export">PhotoInfo.export()</a> provides a simple method to export a photo.  This method actually calls <code class="docutils literal notranslate"><span class="pre">PhotoExporter.export()</span></code> to do the export.  <code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code> provides many more options to configure the export and report results and this is what the osxphotos command line export tools uses.</p>
<section id="a-name-photoexporter-export-export-dest-filename-none-options-optional-exportoptions-none-exportresults-a">
<h4><span class="raw-html-m2r"><a name="photoexporter-export">export(dest, filename=None, options: Optional[ExportOptions]=None) -> ExportResults</a></span><a class="headerlink" href="#a-name-photoexporter-export-export-dest-filename-none-options-optional-exportoptions-none-exportresults-a" title="Link to this heading">¶</a></h4>
<p>Export a photo.</p>
<p>Args:</p>
<ul class="simple">
<li><p>dest: must be valid destination path or exception raised</p></li>
<li><p>filename: (optional): name of exported picture; if not provided, will use current filename</p></li>
<li><p>options (ExportOptions): optional ExportOptions instance</p></li>
</ul>
<p>Returns: ExportResults instance</p>
<p><em>Note</em>: to use dry run mode, you must set options.dry_run=True and also pass in memory version of export_db, and no-op fileutil (e.g. <code class="docutils literal notranslate"><span class="pre">ExportDBInMemory</span></code> and <code class="docutils literal notranslate"><span class="pre">FileUtilNoOp</span></code>) in options.export_db and options.fileutil respectively.</p>
</section>
<section id="a-name-exportoptions-exportoptions-a">
<h4><span class="raw-html-m2r"><a name="ExportOptions">ExportOptions</a></span><a class="headerlink" href="#a-name-exportoptions-exportoptions-a" title="Link to this heading">¶</a></h4>
<p>Options class for exporting photos with <code class="docutils literal notranslate"><span class="pre">export</span></code></p>
<p>Attributes:</p>
<ul class="simple">
<li><p>convert_to_jpeg (bool): if True, converts non-jpeg images to jpeg</p></li>
<li><p>description_template (str): optional template string that will be rendered for use as photo description</p></li>
<li><p>download_missing: (bool, default=False): if True will attempt to export photo via applescript interaction with Photos if missing (see also use_photokit, use_photos_export)</p></li>
<li><p>dry_run: (bool, default=False): set to True to run in &quot;dry run&quot; mode</p></li>
<li><p>edited: (bool, default=False): if True will export the edited version of the photo otherwise exports the original version</p></li>
<li><p>exiftool_flags (list of str): optional list of flags to pass to exiftool when using exiftool option, e.g [&quot;-m&quot;, &quot;-F&quot;]</p></li>
<li><p>exiftool: (bool, default = False): if True, will use exiftool to write metadata to export file</p></li>
<li><p>export_as_hardlink: (bool, default=False): if True, will hardlink files instead of copying them</p></li>
<li><p>export_db: (ExportDB): instance of a class that conforms to ExportDB with methods for getting/setting data related to exported files to compare update state</p></li>
<li><p>fileutil: (FileUtilABC): class that conforms to FileUtilABC with various file utilities</p></li>
<li><p>ignore_date_modified (bool): for use with sidecar and exiftool; if True, sets EXIF:ModifyDate to EXIF:DateTimeOriginal even if date_modified is set</p></li>
<li><p>ignore_signature (bool, default=False): ignore file signature when used with update (look only at filename)</p></li>
<li><p>increment (bool, default=True): if True, will increment file name until a non-existant name is found if overwrite=False and increment=False, export will fail if destination file already exists</p></li>
<li><p>jpeg_ext (str): if set, will use this value for extension on jpegs converted to jpeg with convert_to_jpeg; if not set, uses jpeg; do not include the leading &quot;.&quot;</p></li>
<li><p>jpeg_quality (float in range 0.0 &lt;= jpeg_quality &lt;= 1.0): a value of 1.0 specifies use best quality, a value of 0.0 specifies use maximum compression.</p></li>
<li><p>keyword_template (list of str): list of template strings that will be rendered as used as keywords</p></li>
<li><p>live_photo (bool, default=False): if True, will also export the associated .mov for live photos</p></li>
<li><p>location (bool): if True, include location in exported metadata</p></li>
<li><p>merge_exif_keywords (bool): if True, merged keywords found in file's exif data (requires exiftool)</p></li>
<li><p>merge_exif_persons (bool): if True, merged persons found in file's exif data (requires exiftool)</p></li>
<li><p>overwrite (bool, default=False): if True will overwrite files if they already exist</p></li>
<li><p>persons (bool): if True, include persons in exported metadata</p></li>
<li><p>preview_suffix (str): optional string to append to end of filename for preview images</p></li>
<li><p>preview (bool): if True, also exports preview image</p></li>
<li><p>raw_photo (bool, default=False): if True, will also export the associated RAW photo</p></li>
<li><p>render_options (RenderOptions): optional osxphotos.phototemplate.RenderOptions instance to specify options for rendering templates</p></li>
<li><p>replace_keywords (bool): if True, keyword_template replaces any keywords, otherwise it's additive</p></li>
<li><p>sidecar_drop_ext (bool, default=False): if True, drops the photo's extension from sidecar filename (e.g. 'IMG_1234.json' instead of 'IMG_1234.JPG.json')</p></li>
<li><p>sidecar: bit field (int): set to one or more of SIDECAR_XMP, SIDECAR_JSON, SIDECAR_EXIFTOOL</p>
<ul>
<li><p>SIDECAR_JSON: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json; includes exiftool tag group names (e.g. <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-G</span> <span class="pre">-j</span></code>)</p></li>
<li><p>SIDECAR_EXIFTOOL: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json; does not include exiftool tag group names (e.g. <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-j</span></code>)</p></li>
<li><p>SIDECAR_XMP: if set will write an XMP sidecar with IPTC data sidecar filename will be dest/filename.xmp</p></li>
</ul>
</li>
<li><p>strip (bool): if True, strip whitespace from rendered templates</p></li>
<li><p>timeout (int, default=120): timeout in seconds used with use_photos_export</p></li>
<li><p>touch_file (bool, default=False): if True, sets file's modification time upon photo date</p></li>
<li><p>update (bool, default=False): if True export will run in update mode, that is, it will not export the photo if the current version already exists in the destination</p></li>
<li><p>use_albums_as_keywords (bool, default = False): if True, will include album names in keywords when exporting metadata with exiftool or sidecar</p></li>
<li><p>use_persons_as_keywords (bool, default = False): if True, will include person names in keywords when exporting metadata with exiftool or sidecar</p></li>
<li><p>use_photos_export (bool, default=False): if True will attempt to export photo via applescript interaction with Photos even if not missing (see also use_photokit, download_missing)</p></li>
<li><p>use_photokit (bool, default=False): if True, will use photokit to export photos when use_photos_export is True</p></li>
<li><p>verbose (Callable): optional callable function to use for printing verbose text during processing; if None (default), does not print output.</p></li>
<li><p>tmpfile (str): optional path to use for temporary files</p></li>
</ul>
</section>
<section id="a-name-exportresults-exportresults-a">
<h4><span class="raw-html-m2r"><a name="ExportResults">ExportResults</a></span><a class="headerlink" href="#a-name-exportresults-exportresults-a" title="Link to this heading">¶</a></h4>
<p><code class="docutils literal notranslate"><span class="pre">PhotoExporter().export()</span></code> returns an instance of this class.</p>
<p><code class="docutils literal notranslate"><span class="pre">ExportResults</span></code> has the following properties:</p>
<ul class="simple">
<li><p>datetime: date/time of export in ISO 8601 format</p></li>
<li><p>exported: list of all exported files (A single call to export could export more than one file, e.g. original file, preview, live video, raw, etc.)</p></li>
<li><p>new: list of new files exported when used with update=True</p></li>
<li><p>updated: list of updated files when used with update=True</p></li>
<li><p>skipped: list of skipped files when used with update=True</p></li>
<li><p>exif_updated: list of updated files when used with update=True and exiftool</p></li>
<li><p>touched: list of files touched during export (e.g. file date/time updated with touch_file=True)</p></li>
<li><p>to_touch: Reserved for internal use of export</p></li>
<li><p>converted_to_jpeg: list of files converted to jpeg when convert_to_jpeg=True</p></li>
<li><p>metadata_changed: list of filenames that had metadata changes since last export</p></li>
<li><p>sidecar_json_written: list of JSON sidecars written</p></li>
<li><p>sidecar_json_skipped: list of JSON sidecars skipped when update=True</p></li>
<li><p>sidecar_exiftool_written: list of exiftool sidecars written</p></li>
<li><p>sidecar_exiftool_skipped: list of exiftool sidecars skipped when update=True</p></li>
<li><p>sidecar_xmp_written: list of XMP sidecars written</p></li>
<li><p>sidecar_xmp_skipped: list of XMP sidecars skipped when update=True</p></li>
<li><p>missing: list of missing files</p></li>
<li><p>error: list of tuples containing (filename, error) if error generated during export</p></li>
<li><p>exiftool_warning: list of warnings generated by exiftool during export</p></li>
<li><p>exiftool_error: list of errors generated by exiftool during export</p></li>
<li><p>xattr_written: list of files with extended attributes written during export</p></li>
<li><p>xattr_skipped: list of files where extended attributes were skipped when update=True</p></li>
<li><p>deleted_files: reserved for use by osxphotos CLI</p></li>
<li><p>deleted_directories: reserved for use by osxphotos CLI</p></li>
<li><p>exported_album: reserved for use by osxphotos CLI</p></li>
<li><p>skipped_album: reserved for use by osxphotos CLI</p></li>
<li><p>missing_album: reserved for use by osxphotos CLI</p></li>
</ul>
</section>
</section>
<section id="a-name-exifwriter-exifwriter-a">
<h3><span class="raw-html-m2r"><a name="exifwriter">ExifWriter</a></span><a class="headerlink" href="#a-name-exifwriter-exifwriter-a" title="Link to this heading">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">osxphotos.exifwriter.ExifWriter</span></code> provides a way to write EXIF metadata (using <a class="reference external" href="https://exiftool.org/">exiftool</a>) to files. It is used by <code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code> to write metadata to exported files.  It can also be used independently of <code class="docutils literal notranslate"><span class="pre">PhotoExporter</span></code> to write metadata to files.  <code class="docutils literal notranslate"><span class="pre">ExifWriter</span></code> uses an <code class="docutils literal notranslate"><span class="pre">ExifOptions</span></code> options class to configure the output metadata. For example, <code class="docutils literal notranslate"><span class="pre">ExifOptions.description_template</span></code> allows you to specify a template to use for writing the <code class="docutils literal notranslate"><span class="pre">XMP:Description</span></code> field.</p>
<p><code class="docutils literal notranslate"><span class="pre">ExifWriter</span></code> usage:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.exifwriter</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExifOptions</span><span class="p">,</span> <span class="n">ExifWriter</span>
<span class="c1"># photo is a PhotoInfo object</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">ExifWriter</span><span class="p">(</span><span class="n">photo</span><span class="p">)</span>
<span class="n">options</span> <span class="o">=</span> <span class="n">ExifOptions</span><span class="p">(</span><span class="n">merge_exif_keywords</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># filepath is the path to the file you want to write the metadata to</span>
<span class="n">writer</span><span class="o">.</span><span class="n">write_exif_data</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
</pre></div>
</div>
<p>You can also retrieve the dictionary that will be used to write the metadata without actually writing to file using <code class="docutils literal notranslate"><span class="pre">ExifWriter().exiftool_dict()</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">ExifOptions</span></code> has the following properties:</p>
<ul class="simple">
<li><p>description_template (str): Optional template string that will be rendered for use as photo description</p></li>
<li><p>exiftool_flags (list of str): Optional list of flags to pass to exiftool when using exiftool option, e.g [&quot;-m&quot;, &quot;-F&quot;]</p></li>
<li><p>exiftool: (bool, default = False): if True, will use exiftool to write metadata to export file</p></li>
<li><p>face_regions: (bool, default=True): if True, will export face regions</p></li>
<li><p>ignore_date_modified (bool): for use with sidecar and exiftool; if True, sets EXIF:ModifyDate to EXIF:DateTimeOriginal even if date_modified is set</p></li>
<li><p>keyword_template (list of str): list of template strings that will be rendered as used as keywords</p></li>
<li><p>location (bool): if True, include location in exported metadata</p></li>
<li><p>merge_exif_keywords (bool): if True, merged keywords found in file's exif data (requires exiftool)</p></li>
<li><p>merge_exif_persons (bool): if True, merged persons found in file's exif data (requires exiftool)</p></li>
<li><p>persons (bool): if True, include persons in exported metadata</p></li>
<li><p>render_options (RenderOptions): Optional osxphotos.phototemplate.RenderOptions instance to specify options for rendering templates</p></li>
<li><p>replace_keywords (bool): if True, keyword_template replaces any keywords, otherwise it's additive</p></li>
<li><p>strip (bool): if True, strip whitespace from rendered templates</p></li>
<li><p>use_albums_as_keywords (bool, default = False): if True, will include album names in keywords when exporting metadata with exiftool or sidecar</p></li>
<li><p>use_persons_as_keywords (bool, default = False): if True, will include person names in keywords when exporting metadata with exiftool or sidecar</p></li>
<li><p>favorite_rating (bool): if True, set XMP:Rating=5 for favorite images and XMP:Rating=0 for non-favorites</p></li>
</ul>
</section>
<section id="a-name-sidecarwriter-sidecarwriter-a">
<h3><span class="raw-html-m2r"><a name="sidecarwriter">SidecarWriter</a></span><a class="headerlink" href="#a-name-sidecarwriter-sidecarwriter-a" title="Link to this heading">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">osxphotos.sidecars.SidecarWriter</span></code> is a utility class used by <a class="reference external" href="#photoexporter">PhotoExporter</a> to write the sidecars (XMP, JSON, exiftool) for exported images. You can use this yourself to write sidecars if needed.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.sidecars</span><span class="w"> </span><span class="kn">import</span> <span class="n">SidecarWriter</span>

<span class="c1"># photo is a PhotoInfo object</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">SidecarWriter</span><span class="p">(</span><span class="n">photo</span><span class="p">)</span>

<span class="c1"># dest is destination folder for sidecar files, options is an ExportOptions, export_results is an ExportResults</span>
<span class="c1"># returns ExportResults of sidecars written or skipped</span>
<span class="n">results</span> <span class="o">=</span> <span class="n">writer</span><span class="o">.</span><span class="n">write_sidecar_files</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">export_results</span><span class="p">)</span>
</pre></div>
</div>
<p>You can get the string for the XMP sidecar with <code class="docutils literal notranslate"><span class="pre">xmp_sidecar()</span></code>:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">xmp_sidecar</span><span class="p">(</span>
    <span class="n">photo</span><span class="p">:</span> <span class="n">PhotoInfo</span><span class="p">,</span>
    <span class="n">options</span><span class="p">:</span> <span class="n">ExportOptions</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
    <span class="n">extension</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Returns string for XMP sidecar</span>

<span class="sd">    Args:</span>
<span class="sd">        photo (PhotoInfo): photo to generate sidecars</span>
<span class="sd">        options (ExportOptions): options for export</span>
<span class="sd">        extension (Optional[str]): which extension to use for SidecarForExtension property</span>

<span class="sd">    Returns:</span>
<span class="sd">        str: string containing XMP sidecar</span>
<span class="sd">    &quot;&quot;&quot;</span>
</pre></div>
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.sidecars</span><span class="w"> </span><span class="kn">import</span> <span class="n">xmp_sidecar</span>

<span class="n">sidecar</span> <span class="o">=</span> <span class="n">xmp_sidecar</span><span class="p">(</span><span class="n">photo</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">extension</span><span class="p">)</span>
</pre></div>
</div>
<p>See implementation for more information.</p>
<p>The JSON string for the exiftool sidecar can be retrieved using the function <code class="docutils literal notranslate"><span class="pre">exiftool_json_sidecar</span></code> which has the following signature:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">exiftool_json_sidecar</span><span class="p">(</span>
    <span class="n">photo</span><span class="p">:</span> <span class="n">PhotoInfo</span><span class="p">,</span>
    <span class="n">options</span><span class="p">:</span> <span class="n">ExportOptions</span> <span class="o">|</span> <span class="n">ExifOptions</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
    <span class="n">tag_groups</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
    <span class="n">filename</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</pre></div>
</div>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.sidecars</span><span class="w"> </span><span class="kn">import</span> <span class="n">exiftool_json_sidecar</span>

<span class="n">sidecar</span> <span class="o">=</span> <span class="n">exiftool_json_sidecar</span><span class="p">(</span><span class="n">photo</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">tag_groups</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
</pre></div>
</div>
<p>See source code for full details.</p>
</section>
<section id="a-name-photosalbum-photosalbum-a">
<h3><span class="raw-html-m2r"><a name="photosalbum">PhotosAlbum</a></span><a class="headerlink" href="#a-name-photosalbum-photosalbum-a" title="Link to this heading">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">osxphotos.photosalbum.PhotosAlbum</span></code> is a class that represents a Photos album. It is useful for creating albums and adding <code class="docutils literal notranslate"><span class="pre">PhotoInfo</span></code> assets to albums in Photos. It uses <a class="reference external" href="https://github.com/RhetTbull/PhotoScript">PhotoScript</a>, a Python wrapper around AppleScript, to interact with Photos. An album is created or retrieved using <code class="docutils literal notranslate"><span class="pre">__init__()</span></code>: <code class="docutils literal notranslate"><span class="pre">album</span> <span class="pre">=</span> <span class="pre">PhotosAlbum(name)</span></code> will create the album if it doesn't exist or retrieve it if it does. You can add photos to the album using <code class="docutils literal notranslate"><span class="pre">append()</span></code> and <code class="docutils literal notranslate"><span class="pre">extend()</span></code> as in Python lists or <code class="docutils literal notranslate"><span class="pre">add()</span></code> and <code class="docutils literal notranslate"><span class="pre">update()</span></code> as in Python sets (<code class="docutils literal notranslate"><span class="pre">append()</span></code> and <code class="docutils literal notranslate"><span class="pre">add()</span></code> call the same function as do <code class="docutils literal notranslate"><span class="pre">extend()</span></code> and <code class="docutils literal notranslate"><span class="pre">update()</span></code>). Albums behave as sets as adding a asset that is already in the album has no effect. Assets cannot be removed from an album using this class due to limitations in the Photos AppleScript interface.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot;Example that shows how to add PhotoInfo objects to an album in Photos&quot;&quot;&quot;</span>

<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos</span><span class="w"> </span><span class="kn">import</span> <span class="n">PhotosDB</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.photosalbum</span><span class="w"> </span><span class="kn">import</span> <span class="n">PhotosAlbum</span>

<span class="c1"># If album exists it will be used, otherwise it will be created</span>
<span class="n">album</span> <span class="o">=</span> <span class="n">PhotosAlbum</span><span class="p">(</span><span class="s2">&quot;Best Photos&quot;</span><span class="p">)</span>
<span class="n">best_photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">PhotosDB</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="nb">print</span><span class="p">)</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">score</span><span class="o">.</span><span class="n">overall</span> <span class="o">&gt;</span> <span class="mf">0.9</span><span class="p">]</span>

<span class="c1"># use album.add() or album.append() to add a single photo</span>
<span class="c1"># use album.update() or album.extend() to add an iterable of photos</span>
<span class="n">album</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">best_photos</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Added </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">best_photos</span><span class="p">)</span><span class="si">}</span><span class="s2"> photos to album </span><span class="si">{</span><span class="n">album</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Album contains </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">album</span><span class="o">.</span><span class="n">photos</span><span class="p">())</span><span class="si">}</span><span class="s2"> photos&quot;</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="a-name-textdetection-text-detection-a">
<h3><span class="raw-html-m2r"><a name="textdetection">Text Detection</a></span><a class="headerlink" href="#a-name-textdetection-text-detection-a" title="Link to this heading">¶</a></h3>
<p>The <a class="reference external" href="#photoinfo-detected_text">PhotoInfo.detected_text()</a> and the <code class="docutils literal notranslate"><span class="pre">{detected_text}</span></code> template will perform text detection on the photos in your library. Text detection is a slow process so to avoid unnecessary re-processing of photos, osxphotos will cache the results of the text detection process as an extended attribute on the photo image file.  Extended attributes do not modify the actual file.  The extended attribute is named <code class="docutils literal notranslate"><span class="pre">osxphotos.metadata:detected_text</span></code> and can be viewed using the built-in <a class="reference external" href="https://ss64.com/osx/xattr.html">xattr</a> command or my <a class="reference external" href="https://github.com/RhetTbull/osxmetadata">osxmetadata</a> tool.  If you want to remove the cached attribute, you can do so with <code class="docutils literal notranslate"><span class="pre">xattr</span></code> as follows:</p>
<p><code class="docutils literal notranslate"><span class="pre">find</span> <span class="pre">~/Pictures/Photos\</span> <span class="pre">Library.photoslibrary</span> <span class="pre">|</span> <span class="pre">xargs</span> <span class="pre">-I{}</span> <span class="pre">xattr</span> <span class="pre">-c</span> <span class="pre">osxphotos.metadata:detected_text</span> <span class="pre">'{}'</span></code></p>
</section>
<section id="a-name-comparelibraries-compare-libraries-a">
<h3><span class="raw-html-m2r"><a name="comparelibraries">Compare Libraries</a></span><a class="headerlink" href="#a-name-comparelibraries-compare-libraries-a" title="Link to this heading">¶</a></h3>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">osxphotos.compare_libraries</span><span class="w"> </span><span class="kn">import</span> <span class="n">compare_photos_libraries</span><span class="p">,</span> <span class="n">PhotosDBDiff</span>
</pre></div>
</div>
<section id="a-name-compare-photos-libraries-compare-photos-libraries-a">
<h4><span class="raw-html-m2r"><a name="compare-photos-libraries">compare_photos_libraries()</a></span><a class="headerlink" href="#a-name-compare-photos-libraries-compare-photos-libraries-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">compare_photos_libraries</span><span class="p">(</span>
    <span class="n">library_a</span><span class="p">:</span> <span class="n">PhotosDB</span><span class="p">,</span>
    <span class="n">library_b</span><span class="p">:</span> <span class="n">PhotosDB</span><span class="p">,</span>
    <span class="n">verbose</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">Any</span><span class="p">],</span> <span class="nb">bool</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
    <span class="n">signature_function</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
    <span class="n">diff_function</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">PhotoInfo</span><span class="p">,</span> <span class="n">PhotoInfo</span><span class="p">],</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="n">PhotosDBDiff</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Compare two Photos libraries and return a PhotosDBDiff object</span>

<span class="sd">    Args:</span>
<span class="sd">        library_a: PhotosDB object for first library</span>
<span class="sd">        library_b: PhotosDB object for second library</span>
<span class="sd">        verbose: function to print verbose output, defaults to None</span>
<span class="sd">        signature_function: function to compute signature for a PhotoInfo object, defaults to None</span>
<span class="sd">        diff_function: function to compare two PhotoInfo objects, defaults to None</span>

<span class="sd">    Returns: PhotosDBDiff object</span>

<span class="sd">    Note: signature_function should take a PhotoInfo object as input and return a unique</span>
<span class="sd">        signature for the photo; if signature_function is None, the default signature</span>
<span class="sd">        function will be used which computes a signature based on the photo&#39;s fingerprint</span>
<span class="sd">        diff_function should take two PhotoInfo objects as input and return a truthy value</span>
<span class="sd">        if the objects are different or a falsy value if they are the same; if diff_function</span>
<span class="sd">        is None, the default diff function will be used which compares the dictionary</span>
<span class="sd">        representation of the PhotoInfo objects.</span>
<span class="sd">    &quot;&quot;&quot;</span>
</pre></div>
</div>
</section>
<section id="a-name-photosdbdiff-photosdbdiff-a">
<h4><span class="raw-html-m2r"><a name="PhotosDBDiff">PhotosDBDiff</a></span><a class="headerlink" href="#a-name-photosdbdiff-photosdbdiff-a" title="Link to this heading">¶</a></h4>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@dataclasses</span><span class="o">.</span><span class="n">dataclass</span>
<span class="k">class</span><span class="w"> </span><span class="nc">PhotosDBDiff</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Class to hold differences between two PhotosDB objects&quot;&quot;&quot;</span>

    <span class="n">library_a</span><span class="p">:</span> <span class="n">PhotosDB</span>
    <span class="n">library_b</span><span class="p">:</span> <span class="n">PhotosDB</span>
    <span class="n">in_a_not_b</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">PhotoInfo</span><span class="p">]</span>
    <span class="n">in_b_not_a</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">PhotoInfo</span><span class="p">]</span>
    <span class="n">in_both_same</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="n">PhotoInfo</span><span class="p">,</span> <span class="n">PhotoInfo</span><span class="p">]]</span>
    <span class="n">in_both_different</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="n">PhotoInfo</span><span class="p">,</span> <span class="n">PhotoInfo</span><span class="p">,</span> <span class="n">Any</span><span class="p">]]</span>
    <span class="n">signature</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">PhotoInfo</span><span class="p">],</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="n">photo_signature</span>
</pre></div>
</div>
<p>This class also the following methods:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">asdict()</span></code>: return dict representation of the diff</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">json(self,</span> <span class="pre">indent=2)</span></code>: return JSON representation of the diff</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">csv(self,</span> <span class="pre">delimiter=&quot;,&quot;)</span> <span class="pre">-&gt;</span> <span class="pre">str</span></code>: return CSV representation of the diff</p></li>
</ul>
<p><code class="docutils literal notranslate"><span class="pre">bool(PhotosDBDiff())</span></code> returns True if there are any differences between the libraries.</p>
</section>
</section>
<section id="a-name-utility-functions-utility-functions-a">
<h3><span class="raw-html-m2r"><a name="utility-functions">Utility Functions</a></span><a class="headerlink" href="#a-name-utility-functions-utility-functions-a" title="Link to this heading">¶</a></h3>
<p>The following functions are located in osxphotos.utils</p>
<section id="a-name-get-system-library-path-get-system-library-path-a">
<h4><span class="raw-html-m2r"><a name="get-system-library-path">get_system_library_path()</a></span><a class="headerlink" href="#a-name-get-system-library-path-get-system-library-path-a" title="Link to this heading">¶</a></h4>
<p><strong>MacOS 10.15 Only</strong> Returns path to System Photo Library as string.  On MacOS version &lt; 10.15, returns None.</p>
</section>
<section id="a-name-get-last-library-path-get-last-library-path-a">
<h4><span class="raw-html-m2r"><a name="get-last-library-path">get_last_library_path()</a></span><a class="headerlink" href="#a-name-get-last-library-path-get-last-library-path-a" title="Link to this heading">¶</a></h4>
<p>Returns path to last opened Photo Library as string.</p>
</section>
<section id="a-name-list-photo-libraries-list-photo-libraries-a">
<h4><span class="raw-html-m2r"><a name="list-photo-libraries">list_photo_libraries()</a></span><a class="headerlink" href="#a-name-list-photo-libraries-list-photo-libraries-a" title="Link to this heading">¶</a></h4>
<p>Returns list of Photos libraries found on the system.  <strong>Note</strong>: On MacOS 10.15, this appears to list all libraries. On older systems, it may not find some libraries if they are not located in ~/Pictures.  Provided for convenience but do not rely on this to find all libraries on the system.</p>
</section>
</section>
</section>
<section id="a-name-additional-examples-additional-examples-a">
<h2><span class="raw-html-m2r"><a name="additional-examples">Additional Examples</a></span><a class="headerlink" href="#a-name-additional-examples-additional-examples-a" title="Link to this heading">¶</a></h2>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">osxphotos</span>

<span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>

    <span class="n">photosdb</span> <span class="o">=</span> <span class="n">osxphotos</span><span class="o">.</span><span class="n">PhotosDB</span><span class="p">(</span><span class="s2">&quot;/Users/smith/Pictures/Photos Library.photoslibrary&quot;</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;db file = </span><span class="si">{</span><span class="n">photosdb</span><span class="o">.</span><span class="n">db_path</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;db version = </span><span class="si">{</span><span class="n">photosdb</span><span class="o">.</span><span class="n">db_version</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>

    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">keywords</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">persons</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">albums</span><span class="p">)</span>

    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">keywords_as_dict</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">persons_as_dict</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">photosdb</span><span class="o">.</span><span class="n">albums_as_dict</span><span class="p">)</span>

    <span class="c1"># find all photos with Keyword = Kids and containing person Katie</span>
    <span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Kids&quot;</span><span class="p">],</span> <span class="n">persons</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Katie&quot;</span><span class="p">])</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;found </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">photos</span><span class="p">)</span><span class="si">}</span><span class="s2"> photos&quot;</span><span class="p">)</span>

    <span class="c1"># find all photos that include Katie but do not contain the keyword wedding</span>
    <span class="n">photos</span> <span class="o">=</span> <span class="p">[</span>
        <span class="n">p</span>
        <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">persons</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;Katie&quot;</span><span class="p">])</span>
        <span class="k">if</span> <span class="n">p</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span><span class="n">keywords</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;wedding&quot;</span><span class="p">])</span>
    <span class="p">]</span>

    <span class="c1"># get all photos in the database</span>
    <span class="n">photos</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">photos</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span>
            <span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">title</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">keywords</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">albums</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">persons</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">path</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">ismissing</span><span class="p">,</span>
            <span class="n">p</span><span class="o">.</span><span class="n">hasadjustments</span><span class="p">,</span>
        <span class="p">)</span>


<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
</section>
</section>

        </article>
      </div>
      <footer>
        
        <div class="related-pages">
          <a class="next-page" href="reference.html">
              <div class="page-info">
                <div class="context">
                  <span>Next</span>
                </div>
                <div class="title">OSXPhotos Python Reference</div>
              </div>
              <svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
            </a>
          <a class="prev-page" href="package_overview.html">
              <svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
              <div class="page-info">
                <div class="context">
                  <span>Previous</span>
                </div>
                
                <div class="title">OSXPhotos Python Package Overview</div>
                
              </div>
            </a>
        </div>
        <div class="bottom-of-page">
          <div class="left-details">
            <div class="copyright">
                Copyright &#169; 2021, Rhet Turnbull
            </div>
            Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
            
            <a href="https://github.com/pradyunsg/furo">Furo</a>
            
          </div>
          <div class="right-details">
            
          </div>
        </div>
        
      </footer>
    </div>
    <aside class="toc-drawer">
      
      
      <div class="toc-sticky toc-scroll">
        <div class="toc-title-container">
          <span class="toc-title">
            On this page
          </span>
        </div>
        <div class="toc-tree-container">
          <div class="toc-tree">
            <ul>
<li><a class="reference internal" href="#">OSXPhotos Python API</a><ul>
<li><a class="reference internal" href="#table-of-contents">Table of Contents</a></li>
<li><a class="reference internal" href="#a-name-example-uses-of-the-python-package-example-uses-of-the-python-package-a"><span class="raw-html-m2r"><a name="example-uses-of-the-python-package">Example uses of the Python package</a></span></a><ul>
<li><a class="reference internal" href="#print-filename-date-created-title-and-keywords-for-all-photos-in-a-library">Print filename, date created, title, and keywords for all photos in a library</a></li>
<li><a class="reference internal" href="#a-name-building-simple-command-line-tools-building-simple-command-line-tools-a"><span class="raw-html-m2r"><a name="building-simple-command-line-tools">Building simple command line tools</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-concurrency-concurrency-a"><span class="raw-html-m2r"><a name="concurrency">Concurrency</a></span></a></li>
<li><a class="reference internal" href="#a-name-calling-cli-commands-from-python-calling-cli-commands-from-python-a"><span class="raw-html-m2r"><a name="calling-cli-commands-from-python">Calling CLI commands from Python</a></span></a></li>
<li><a class="reference internal" href="#a-name-package-interface-package-interface-a"><span class="raw-html-m2r"><a name="package-interface">Package Interface</a></span></a><ul>
<li><a class="reference internal" href="#a-name-photosdb-photosdb-a"><span class="raw-html-m2r"><a name="photosdb">PhotosDB</a></span></a><ul>
<li><a class="reference internal" href="#read-a-photos-library-database">Read a Photos library database</a></li>
<li><a class="reference internal" href="#open-the-default-last-opened-photos-library">Open the default (last opened) Photos library</a></li>
<li><a class="reference internal" href="#open-system-photos-library">Open System Photos library</a></li>
<li><a class="reference internal" href="#open-a-specific-photos-library">Open a specific Photos library</a></li>
<li><a class="reference internal" href="#a-name-photosdbphotos-photos-keywords-none-uuid-none-persons-none-albums-none-images-true-movies-true-from-date-none-to-date-none-intrash-false-a"><span class="raw-html-m2r"><a name="photosdbphotos">photos(keywords=None, uuid=None, persons=None, albums=None, images=True, movies=True, from_date=None, to_date=None, intrash=False)</a></span></a></li>
<li><a class="reference internal" href="#a-name-getphoto-get-photo-uuid-a"><span class="raw-html-m2r"><a name="getphoto">get_photo(uuid)</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-query-query-options-queryoptions-list-photoinfo-a"><span class="raw-html-m2r"><a name="photosdb-query">query(options: QueryOptions) -> List[PhotoInfo]:</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-keywords-keywords-a"><span class="raw-html-m2r"><a name="photosdb-keywords">keywords</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-albuminfo-album-info-a"><span class="raw-html-m2r"><a name="photosdb-albuminfo">album_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-albums-albums-a"><span class="raw-html-m2r"><a name="photosdb-albums">albums</a></span></a></li>
<li><a class="reference internal" href="#a-name-albums-shared-albums-shared-a"><span class="raw-html-m2r"><a name="albums-shared">albums_shared</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-import-info-import-info-a"><span class="raw-html-m2r"><a name="photosdb-import-info">import_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-project-info-project-info-a"><span class="raw-html-m2r"><a name="photosdb-project-info">project_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-moment-info-moment-info-a"><span class="raw-html-m2r"><a name="photosdb-moment-info">moment_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-folder-info-folder-info-a"><span class="raw-html-m2r"><a name="photosdb-folder-info">folder_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-folders-folders-a"><span class="raw-html-m2r"><a name="photosdb-folders">folders</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-persons-persons-a"><span class="raw-html-m2r"><a name="photosdb-persons">persons</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-person-info-person-info-a"><span class="raw-html-m2r"><a name="photosdb-person-info">person_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-keywords-as-dict-keywords-as-dict-a"><span class="raw-html-m2r"><a name="keywords-as-dict">keywords_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-keywords-without-photo-keywords-without-photo-a"><span class="raw-html-m2r"><a name="keywords-without-photo">keywords_without_photo</a></span></a></li>
<li><a class="reference internal" href="#a-name-persons-as-dict-persons-as-dict-a"><span class="raw-html-m2r"><a name="persons-as-dict">persons_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-albums-as-dict-albums-as-dict-a"><span class="raw-html-m2r"><a name="albums-as-dict">albums_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-albums-shared-as-dict-albums-shared-as-dict-a"><span class="raw-html-m2r"><a name="albums-shared-as-dict">albums_shared_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-labels-labels-a"><span class="raw-html-m2r"><a name="photosdb-labels">labels</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdb-labels-normalized-labels-normalized-a"><span class="raw-html-m2r"><a name="photosdb-labels-normalized">labels_normalized</a></span></a></li>
<li><a class="reference internal" href="#a-name-labels-as-dict-labels-as-dict-a"><span class="raw-html-m2r"><a name="labels-as-dict">labels_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-labels-normalized-as-dict-labels-normalized-as-dict-a"><span class="raw-html-m2r"><a name="labels-normalized-as-dict">labels_normalized_as_dict</a></span></a></li>
<li><a class="reference internal" href="#a-name-library-path-library-path-a"><span class="raw-html-m2r"><a name="library-path">library_path</a></span></a></li>
<li><a class="reference internal" href="#a-name-db-path-db-path-a"><span class="raw-html-m2r"><a name="db-path">db_path</a></span></a></li>
<li><a class="reference internal" href="#a-name-db-version-db-version-a"><span class="raw-html-m2r"><a name="db-version">db_version</a></span></a></li>
<li><a class="reference internal" href="#a-name-photos-version-photos-version-a"><span class="raw-html-m2r"><a name="photos-version">photos_version</a></span></a></li>
<li><a class="reference internal" href="#a-name-get-db-connection-get-db-connection-a"><span class="raw-html-m2r"><a name="get-db-connection">get_db_connection()</a></span></a></li>
<li><a class="reference internal" href="#a-name-executesql-execute-sql-a"><span class="raw-html-m2r"><a name="executesql">execute(sql)</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-queryoptions-queryoptions-a"><span class="raw-html-m2r"><a name="queryoptions">QueryOptions</a></span></a><ul>
<li><a class="reference internal" href="#a-name-attributes-attributes-a"><span class="raw-html-m2r"><a name="Attributes">Attributes</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-photoinfo-photoinfo-a"><span class="raw-html-m2r"><a name="photoinfo">PhotoInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-photoinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="photoinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#a-name-filename-filename-a"><span class="raw-html-m2r"><a name="filename">filename</a></span></a></li>
<li><a class="reference internal" href="#a-name-original-filename-original-filename-a"><span class="raw-html-m2r"><a name="original-filename">original_filename</a></span></a></li>
<li><a class="reference internal" href="#a-name-date-date-a"><span class="raw-html-m2r"><a name="date">date</a></span></a></li>
<li><a class="reference internal" href="#a-name-tzoffset-tzoffset-a"><span class="raw-html-m2r"><a name="tzoffset">tzoffset</a></span></a></li>
<li><a class="reference internal" href="#a-name-tzname-tzname-a"><span class="raw-html-m2r"><a name="tzname">tzname</a></span></a></li>
<li><a class="reference internal" href="#a-name-date-original-date-original-a"><span class="raw-html-m2r"><a name="date-original">date_original</a></span></a></li>
<li><a class="reference internal" href="#a-name-date-added-date-added-a"><span class="raw-html-m2r"><a name="date-added">date_added</a></span></a></li>
<li><a class="reference internal" href="#a-name-date-modified-date-modified-a"><span class="raw-html-m2r"><a name="date-modified">date_modified</a></span></a></li>
<li><a class="reference internal" href="#a-name-description-description-a"><span class="raw-html-m2r"><a name="description">description</a></span></a></li>
<li><a class="reference internal" href="#a-name-title-title-a"><span class="raw-html-m2r"><a name="title">title</a></span></a></li>
<li><a class="reference internal" href="#a-name-keywords-keywords-a"><span class="raw-html-m2r"><a name="keywords">keywords</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-albums-albums-a"><span class="raw-html-m2r"><a name="photoinfo-albums">albums</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-album-info-album-info-a"><span class="raw-html-m2r"><a name="photoinfo-album-info">album_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-import-info-import-info-a"><span class="raw-html-m2r"><a name="import-info">import_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-project-info-project-info-a"><span class="raw-html-m2r"><a name="project-info">project_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-persons-persons-a"><span class="raw-html-m2r"><a name="persons">persons</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-personinfo-person-info-a"><span class="raw-html-m2r"><a name="photoinfo-personinfo">person_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-face-info-face-info-a"><span class="raw-html-m2r"><a name="photoinfo-face-info">face_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-path-a"><span class="raw-html-m2r"><a name="path">path</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-edited-path-edited-a"><span class="raw-html-m2r"><a name="path-edited">path_edited</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-derivatives-path-derivatives-a"><span class="raw-html-m2r"><a name="path-derivatives">path_derivatives</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-raw-path-raw-a"><span class="raw-html-m2r"><a name="path-raw">path_raw</a></span></a></li>
<li><a class="reference internal" href="#a-name-has-raw-has-raw-a"><span class="raw-html-m2r"><a name="has-raw">has_raw</a></span></a></li>
<li><a class="reference internal" href="#a-name-israw-israw-a"><span class="raw-html-m2r"><a name="israw">israw</a></span></a></li>
<li><a class="reference internal" href="#a-name-raw-original-raw-original-a"><span class="raw-html-m2r"><a name="raw-original">raw_original</a></span></a></li>
<li><a class="reference internal" href="#a-name-height-height-a"><span class="raw-html-m2r"><a name="height">height</a></span></a></li>
<li><a class="reference internal" href="#a-name-width-width-a"><span class="raw-html-m2r"><a name="width">width</a></span></a></li>
<li><a class="reference internal" href="#a-name-orientation-orientation-a"><span class="raw-html-m2r"><a name="orientation">orientation</a></span></a></li>
<li><a class="reference internal" href="#a-name-original-height-original-height-a"><span class="raw-html-m2r"><a name="original-height">original_height</a></span></a></li>
<li><a class="reference internal" href="#a-name-original-width-original-width-a"><span class="raw-html-m2r"><a name="original-width">original_width</a></span></a></li>
<li><a class="reference internal" href="#a-name-original-orientation-original-orientation-a"><span class="raw-html-m2r"><a name="original-orientation">original_orientation</a></span></a></li>
<li><a class="reference internal" href="#a-name-original-filesize-original-filesize-a"><span class="raw-html-m2r"><a name="original-filesize">original_filesize</a></span></a></li>
<li><a class="reference internal" href="#a-name-ismissing-ismissing-a"><span class="raw-html-m2r"><a name="ismissing">ismissing</a></span></a></li>
<li><a class="reference internal" href="#a-name-hasadjustments-hasadjustments-a"><span class="raw-html-m2r"><a name="hasadjustments">hasadjustments</a></span></a></li>
<li><a class="reference internal" href="#a-name-adjustments-adjustments-a"><span class="raw-html-m2r"><a name="adjustments">adjustments</a></span></a></li>
<li><a class="reference internal" href="#a-name-adjustment-type-adjustment-type-a"><span class="raw-html-m2r"><a name="adjustment_type">adjustment_type</a></span></a></li>
<li><a class="reference internal" href="#a-name-external-edit-external-edit-a"><span class="raw-html-m2r"><a name="external-edit">external_edit</a></span></a></li>
<li><a class="reference internal" href="#a-name-favorite-favorite-a"><span class="raw-html-m2r"><a name="favorite">favorite</a></span></a></li>
<li><a class="reference internal" href="#a-name-flagged-flagged-a"><span class="raw-html-m2r"><a name="flagged">flagged</a></span></a></li>
<li><a class="reference internal" href="#a-name-rating-rating-a"><span class="raw-html-m2r"><a name="rating">rating</a></span></a></li>
<li><a class="reference internal" href="#a-name-hidden-hidden-a"><span class="raw-html-m2r"><a name="hidden">hidden</a></span></a></li>
<li><a class="reference internal" href="#a-name-visible-visible-a"><span class="raw-html-m2r"><a name="visible">visible</a></span></a></li>
<li><a class="reference internal" href="#a-name-intrash-intrash-a"><span class="raw-html-m2r"><a name="intrash">intrash</a></span></a></li>
<li><a class="reference internal" href="#a-name-date-trashed-date-trashed-a"><span class="raw-html-m2r"><a name="date-trashed">date_trashed</a></span></a></li>
<li><a class="reference internal" href="#a-name-location-location-a"><span class="raw-html-m2r"><a name="location">location</a></span></a></li>
<li><a class="reference internal" href="#a-name-latitude-latitude-a"><span class="raw-html-m2r"><a name="latitude">latitude</a></span></a></li>
<li><a class="reference internal" href="#a-name-longitude-longitude-a"><span class="raw-html-m2r"><a name="longitude">longitude</a></span></a></li>
<li><a class="reference internal" href="#a-name-place-place-a"><span class="raw-html-m2r"><a name="place">place</a></span></a></li>
<li><a class="reference internal" href="#a-name-shared-shared-a"><span class="raw-html-m2r"><a name="shared">shared</a></span></a></li>
<li><a class="reference internal" href="#a-name-owner-owner-a"><span class="raw-html-m2r"><a name="owner">owner</a></span></a></li>
<li><a class="reference internal" href="#a-name-comments-comments-a"><span class="raw-html-m2r"><a name="comments">comments</a></span></a></li>
<li><a class="reference internal" href="#a-name-likes-likes-a"><span class="raw-html-m2r"><a name="likes">likes</a></span></a></li>
<li><a class="reference internal" href="#a-name-isreference-isreference-a"><span class="raw-html-m2r"><a name="isreference">isreference</a></span></a></li>
<li><a class="reference internal" href="#a-name-isphoto-isphoto-a"><span class="raw-html-m2r"><a name="isphoto">isphoto</a></span></a></li>
<li><a class="reference internal" href="#a-name-ismovie-ismovie-a"><span class="raw-html-m2r"><a name="ismovie">ismovie</a></span></a></li>
<li><a class="reference internal" href="#a-name-iscloudasset-iscloudasset-a"><span class="raw-html-m2r"><a name="iscloudasset">iscloudasset</a></span></a></li>
<li><a class="reference internal" href="#a-name-incloud-incloud-a"><span class="raw-html-m2r"><a name="incloud">incloud</a></span></a></li>
<li><a class="reference internal" href="#a-name-syndicated-syndicated-a"><span class="raw-html-m2r"><a name="syndicated">syndicated</a></span></a></li>
<li><a class="reference internal" href="#a-name-saved-to-library-saved-to-library-a"><span class="raw-html-m2r"><a name="saved-to-library">saved_to_library</a></span></a></li>
<li><a class="reference internal" href="#a-name-shared-moment-shared-moment-a"><span class="raw-html-m2r"><a name="shared-moment">shared_moment</a></span></a></li>
<li><a class="reference internal" href="#a-name-shared-library-shared-library-a"><span class="raw-html-m2r"><a name="shared-library">shared_library</a></span></a></li>
<li><a class="reference internal" href="#a-name-share-participant-info-share-participant-info-a"><span class="raw-html-m2r"><a name="share-participant-info">share_participant_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-share-participants-share-participants-a"><span class="raw-html-m2r"><a name="share-participants">share_participants</a></span></a></li>
<li><a class="reference internal" href="#a-name-uti-uti-a"><span class="raw-html-m2r"><a name="uti">uti</a></span></a></li>
<li><a class="reference internal" href="#a-name-uti-original-uti-original-a"><span class="raw-html-m2r"><a name="uti-original">uti_original</a></span></a></li>
<li><a class="reference internal" href="#a-name-uti-edited-uti-edited-a"><span class="raw-html-m2r"><a name="uti-edited">uti_edited</a></span></a></li>
<li><a class="reference internal" href="#a-name-uti-raw-uti-raw-a"><span class="raw-html-m2r"><a name="uti-raw">uti_raw</a></span></a></li>
<li><a class="reference internal" href="#a-name-burst-burst-a"><span class="raw-html-m2r"><a name="burst">burst</a></span></a></li>
<li><a class="reference internal" href="#a-name-burst-selected-burst-selected-a"><span class="raw-html-m2r"><a name="burst-selected">burst_selected</a></span></a></li>
<li><a class="reference internal" href="#a-name-burst-key-burst-key-a"><span class="raw-html-m2r"><a name="burst-key">burst_key</a></span></a></li>
<li><a class="reference internal" href="#a-name-burst-default-pick-burst-default-pick-a"><span class="raw-html-m2r"><a name="burst-default-pick">burst_default_pick</a></span></a></li>
<li><a class="reference internal" href="#a-name-burst-photos-burst-photos-a"><span class="raw-html-m2r"><a name="burst-photos">burst_photos</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-burst-albums-burst-albums-a"><span class="raw-html-m2r"><a name="photoinfo-burst-albums">burst_albums</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-burst-album-info-burst-album-info-a"><span class="raw-html-m2r"><a name="photoinfo-burst-album-info">burst_album_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-live-photo-live-photo-a"><span class="raw-html-m2r"><a name="live-photo">live_photo</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-live-photo-path-live-photo-a"><span class="raw-html-m2r"><a name="path-live-photo">path_live_photo</a></span></a></li>
<li><a class="reference internal" href="#a-name-path-edited-live-photo-path-edited-live-photo-a"><span class="raw-html-m2r"><a name="path-edited-live-photo">path_edited_live_photo</a></span></a></li>
<li><a class="reference internal" href="#a-name-portrait-portrait-a"><span class="raw-html-m2r"><a name="portrait">portrait</a></span></a></li>
<li><a class="reference internal" href="#a-name-hdr-hdr-a"><span class="raw-html-m2r"><a name="hdr">hdr</a></span></a></li>
<li><a class="reference internal" href="#a-name-selfie-selfie-a"><span class="raw-html-m2r"><a name="selfie">selfie</a></span></a></li>
<li><a class="reference internal" href="#a-name-time-lapse-time-lapse-a"><span class="raw-html-m2r"><a name="time-lapse">time_lapse</a></span></a></li>
<li><a class="reference internal" href="#a-name-panorama-panorama-a"><span class="raw-html-m2r"><a name="panorama">panorama</a></span></a></li>
<li><a class="reference internal" href="#a-name-slow-mo-slow-mo-a"><span class="raw-html-m2r"><a name="slow-mo">slow_mo</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-labels-labels-a"><span class="raw-html-m2r"><a name="photoinfo-labels">labels</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-labels-normalized-labels-normalized-a"><span class="raw-html-m2r"><a name="photoinfo-labels-normalized">labels_normalized</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-searchinfo-search-info-a"><span class="raw-html-m2r"><a name="photoinfo-searchinfo">search_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-search-info-normalized-search-info-normalized-a"><span class="raw-html-m2r"><a name="photoinfo-search-info-normalized">search_info_normalized</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-exif-info-exif-info-a"><span class="raw-html-m2r"><a name="photoinfo-exif-info">exif_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-exiftool-exiftool-a"><span class="raw-html-m2r"><a name="photoinfo-exiftool">exiftool</a></span></a></li>
<li><a class="reference internal" href="#a-name-score-score-a"><span class="raw-html-m2r"><a name="score">score</a></span></a></li>
<li><a class="reference internal" href="#a-name-duplicates-duplicates-a"><span class="raw-html-m2r"><a name="duplicates">duplicates</a></span></a></li>
<li><a class="reference internal" href="#a-name-cloud-guid-cloud-guid-a"><span class="raw-html-m2r"><a name="cloud-guid">cloud_guid</a></span></a></li>
<li><a class="reference internal" href="#a-name-cloud-owner-hashed-id-cloud-owner-hashed-id-a"><span class="raw-html-m2r"><a name="cloud-owner-hashed-id">cloud_owner_hashed_id</a></span></a></li>
<li><a class="reference internal" href="#a-name-fingerprint-fingerprint-a"><span class="raw-html-m2r"><a name="fingerprint">fingerprint</a></span></a></li>
<li><a class="reference internal" href="#a-name-hexdigest-hexdigest-a"><span class="raw-html-m2r"><a name="hexdigest">hexdigest</a></span></a></li>
<li><a class="reference internal" href="#a-name-media-analysis-media-analysis-a"><span class="raw-html-m2r"><a name="media_analysis">media_analysis</a></span></a></li>
<li><a class="reference internal" href="#a-name-ai-caption-ai-caption-a"><span class="raw-html-m2r"><a name="ai_caption">ai_caption</a></span></a></li>
<li><a class="reference internal" href="#a-name-tables-tables-a"><span class="raw-html-m2r"><a name="tables">tables()</a></span></a></li>
<li><a class="reference internal" href="#a-name-json-json-a"><span class="raw-html-m2r"><a name="json">json()</a></span></a></li>
<li><a class="reference internal" href="#a-name-asdict-asdict-a"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-export-export-a"><span class="raw-html-m2r"><a name="photoinfo-export">export()</a></span></a></li>
<li><a class="reference internal" href="#a-name-rendertemplate-render-template-template-str-options-none-a"><span class="raw-html-m2r"><a name="rendertemplate">render_template(template_str, options=None)</a></span></a></li>
<li><a class="reference internal" href="#a-name-photoinfo-detected-text-detected-text-confidence-threshold-text-detection-confidence-threshold-a"><span class="raw-html-m2r"><a name="photoinfo-detected-text">detected_text(confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD)</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-exifinfo-exifinfo-a"><span class="raw-html-m2r"><a name="exifinfo">ExifInfo</a></span></a></li>
<li><a class="reference internal" href="#a-name-albuminfo-albuminfo-a"><span class="raw-html-m2r"><a name="albuminfo">AlbumInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-albuminfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="albuminfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#id63"><span class="raw-html-m2r"><a name="title">title</a></span></a></li>
<li><a class="reference internal" href="#a-name-albumphotos-photos-a"><span class="raw-html-m2r"><a name="albumphotos">photos</a></span></a></li>
<li><a class="reference internal" href="#a-name-creation-date-creation-date-a"><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span></a></li>
<li><a class="reference internal" href="#a-name-start-date-start-date-a"><span class="raw-html-m2r"><a name="start-date">start_date</a></span></a></li>
<li><a class="reference internal" href="#a-name-end-date-end-date-a"><span class="raw-html-m2r"><a name="end-date">end_date</a></span></a></li>
<li><a class="reference internal" href="#a-name-folder-list-folder-list-a"><span class="raw-html-m2r"><a name="folder-list">folder_list</a></span></a></li>
<li><a class="reference internal" href="#a-name-folder-names-folder-names-a"><span class="raw-html-m2r"><a name="folder-names">folder_names</a></span></a></li>
<li><a class="reference internal" href="#a-name-parent-parent-a"><span class="raw-html-m2r"><a name="parent">parent</a></span></a></li>
<li><a class="reference internal" href="#id67"><span class="raw-html-m2r"><a name="owner">owner</a></span></a></li>
<li><a class="reference internal" href="#id68"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-importinfo-importinfo-a"><span class="raw-html-m2r"><a name="importinfo">ImportInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-importinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="importinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#a-name-importphotos-photos-a"><span class="raw-html-m2r"><a name="importphotos">photos</a></span></a></li>
<li><a class="reference internal" href="#id70"><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span></a></li>
<li><a class="reference internal" href="#id71"><span class="raw-html-m2r"><a name="start-date">start_date</a></span></a></li>
<li><a class="reference internal" href="#id72"><span class="raw-html-m2r"><a name="end-date">end_date</a></span></a></li>
<li><a class="reference internal" href="#id73"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-projectinfo-projectinfo-a"><span class="raw-html-m2r"><a name="projectinfo">ProjectInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-projectinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="projectinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#id74"><span class="raw-html-m2r"><a name="title">title</a></span></a></li>
<li><a class="reference internal" href="#a-name-projectphotos-photos-a"><span class="raw-html-m2r"><a name="projectphotos">photos</a></span></a></li>
<li><a class="reference internal" href="#id76"><span class="raw-html-m2r"><a name="creation-date">creation_date</a></span></a></li>
<li><a class="reference internal" href="#id77"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-momentinfo-momentinfo-a"><span class="raw-html-m2r"><a name="momentinfo">MomentInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-pk-pk-a"><span class="raw-html-m2r"><a name="pk">pk</a></span></a></li>
<li><a class="reference internal" href="#id78"><span class="raw-html-m2r"><a name="location">location</a></span></a></li>
<li><a class="reference internal" href="#id79"><span class="raw-html-m2r"><a name="title">title</a></span></a></li>
<li><a class="reference internal" href="#a-name-subtitle-subtitle-a"><span class="raw-html-m2r"><a name="subtitle">subtitle</a></span></a></li>
<li><a class="reference internal" href="#id80"><span class="raw-html-m2r"><a name="start-date">start_date</a></span></a></li>
<li><a class="reference internal" href="#id81"><span class="raw-html-m2r"><a name="end-date">end_date</a></span></a></li>
<li><a class="reference internal" href="#id82"><span class="raw-html-m2r"><a name="date">date</a></span></a></li>
<li><a class="reference internal" href="#a-name-modification-date-modification-date-a"><span class="raw-html-m2r"><a name="modification-date">modification_date</a></span></a></li>
<li><a class="reference internal" href="#a-name-photos-photos-a"><span class="raw-html-m2r"><a name="photos">photos</a></span></a></li>
<li><a class="reference internal" href="#id83"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-folderinfo-folderinfo-a"><span class="raw-html-m2r"><a name="folderinfo">FolderInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-folderinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="folderinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#id84"><span class="raw-html-m2r"><a name="title">title</a></span></a></li>
<li><a class="reference internal" href="#a-name-folderinfo-album-info-album-info-a"><span class="raw-html-m2r"><a name="folderinfo-album-info">album_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-folderinfo-album-info-shared-album-info-shared-a"><span class="raw-html-m2r"><a name="folderinfo-album-info-shared">album_info_shared</a></span></a></li>
<li><a class="reference internal" href="#a-name-subfolders-subfolders-a"><span class="raw-html-m2r"><a name="subfolders">subfolders</a></span></a></li>
<li><a class="reference internal" href="#id88"><span class="raw-html-m2r"><a name="parent">parent</a></span></a></li>
<li><a class="reference internal" href="#a-name-sort-order-sort-order-a"><span class="raw-html-m2r"><a name="sort-order">sort_order</a></span></a></li>
<li><a class="reference internal" href="#a-name-photo-indexphoto-photo-index-photo-a"><span class="raw-html-m2r"><a name="photo-indexphoto">photo_index(photo)</a></span></a></li>
<li><a class="reference internal" href="#id90"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-placeinfo-placeinfo-a"><span class="raw-html-m2r"><a name="placeinfo">PlaceInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-ishome-ishome-a"><span class="raw-html-m2r"><a name="ishome">ishome</a></span></a></li>
<li><a class="reference internal" href="#a-name-name-name-a"><span class="raw-html-m2r"><a name="name">name</a></span></a></li>
<li><a class="reference internal" href="#a-name-names-names-a"><span class="raw-html-m2r"><a name="names">names</a></span></a></li>
<li><a class="reference internal" href="#a-name-country-code-country-code-a"><span class="raw-html-m2r"><a name="country-code">country_code</a></span></a></li>
<li><a class="reference internal" href="#a-name-address-str-address-str-a"><span class="raw-html-m2r"><a name="address-str">address_str</a></span></a></li>
<li><a class="reference internal" href="#a-name-address-address-a"><span class="raw-html-m2r"><a name="address">address</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-scoreinfo-scoreinfo-a"><span class="raw-html-m2r"><a name="scoreinfo">ScoreInfo</a></span></a></li>
<li><a class="reference internal" href="#a-name-searchinfo-searchinfo-a"><span class="raw-html-m2r"><a name="searchinfo">SearchInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-searchinfo-labels-labels-a"><span class="raw-html-m2r"><a name="searchinfo-labels">labels</a></span></a></li>
<li><a class="reference internal" href="#a-name-place-names-place-names-a"><span class="raw-html-m2r"><a name="place-names">place_names</a></span></a></li>
<li><a class="reference internal" href="#a-name-streets-streets-a"><span class="raw-html-m2r"><a name="streets">streets</a></span></a></li>
<li><a class="reference internal" href="#a-name-neighborhoods-neighborhoods-a"><span class="raw-html-m2r"><a name="neighborhoods">neighborhoods</a></span></a></li>
<li><a class="reference internal" href="#a-name-locality-names-locality-names-a"><span class="raw-html-m2r"><a name="locality-names">locality_names</a></span></a></li>
<li><a class="reference internal" href="#a-name-city-city-a"><span class="raw-html-m2r"><a name="city">city</a></span></a></li>
<li><a class="reference internal" href="#a-name-state-state-a"><span class="raw-html-m2r"><a name="state">state</a></span></a></li>
<li><a class="reference internal" href="#a-name-state-abbreviation-state-abbreviation-a"><span class="raw-html-m2r"><a name="state-abbreviation">state_abbreviation</a></span></a></li>
<li><a class="reference internal" href="#a-name-country-country-a"><span class="raw-html-m2r"><a name="country">country</a></span></a></li>
<li><a class="reference internal" href="#a-name-month-month-a"><span class="raw-html-m2r"><a name="month">month</a></span></a></li>
<li><a class="reference internal" href="#a-name-year-year-a"><span class="raw-html-m2r"><a name="year">year</a></span></a></li>
<li><a class="reference internal" href="#a-name-bodies-of-water-bodies-of-water-a"><span class="raw-html-m2r"><a name="bodies-of-water">bodies_of_water</a></span></a></li>
<li><a class="reference internal" href="#a-name-holidays-holidays-a"><span class="raw-html-m2r"><a name="holidays">holidays</a></span></a></li>
<li><a class="reference internal" href="#a-name-activities-activities-a"><span class="raw-html-m2r"><a name="activities">activities</a></span></a></li>
<li><a class="reference internal" href="#a-name-season-season-a"><span class="raw-html-m2r"><a name="season">season</a></span></a></li>
<li><a class="reference internal" href="#a-name-venues-venues-a"><span class="raw-html-m2r"><a name="venues">venues</a></span></a></li>
<li><a class="reference internal" href="#a-name-venue-types-venue-types-a"><span class="raw-html-m2r"><a name="venue-types">venue_types</a></span></a></li>
<li><a class="reference internal" href="#a-name-media-types-media-types-a"><span class="raw-html-m2r"><a name="media-types">media_types</a></span></a></li>
<li><a class="reference internal" href="#a-name-all-all-a"><span class="raw-html-m2r"><a name="all">all</a></span></a></li>
<li><a class="reference internal" href="#id91"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-personinfo-personinfo-a"><span class="raw-html-m2r"><a name="personinfo">PersonInfo</a></span></a><ul>
<li><a class="reference internal" href="#id92"><span class="raw-html-m2r"><a name="name">name</a></span></a></li>
<li><a class="reference internal" href="#a-name-display-name-display-name-a"><span class="raw-html-m2r"><a name="display-name">display_name</a></span></a></li>
<li><a class="reference internal" href="#a-name-personinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="personinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#a-name-keyphoto-keyphoto-a"><span class="raw-html-m2r"><a name="keyphoto">keyphoto</a></span></a></li>
<li><a class="reference internal" href="#a-name-facecount-facecount-a"><span class="raw-html-m2r"><a name="facecount">facecount</a></span></a></li>
<li><a class="reference internal" href="#a-name-personphotos-photos-a"><span class="raw-html-m2r"><a name="personphotos">photos</a></span></a></li>
<li><a class="reference internal" href="#a-name-person-face-info-face-info-a"><span class="raw-html-m2r"><a name="person-face-info">face_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-personfavorite-favorite-a"><span class="raw-html-m2r"><a name="personfavorite">favorite</a></span></a></li>
<li><a class="reference internal" href="#a-name-personsortorder-sort-order-a"><span class="raw-html-m2r"><a name="personsortorder">sort_order</a></span></a></li>
<li><a class="reference internal" href="#id94"><span class="raw-html-m2r"><a name="json">json()</a></span></a></li>
<li><a class="reference internal" href="#id95"><span class="raw-html-m2r"><a name="asdict">asdict()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-faceinfo-faceinfo-a"><span class="raw-html-m2r"><a name="faceinfo">FaceInfo</a></span></a><ul>
<li><a class="reference internal" href="#a-name-faceinfo-uuid-uuid-a"><span class="raw-html-m2r"><a name="faceinfo-uuid">uuid</a></span></a></li>
<li><a class="reference internal" href="#a-name-faceinfo-name-name-a"><span class="raw-html-m2r"><a name="faceinfo-name">name</a></span></a></li>
<li><a class="reference internal" href="#a-name-asset-uuid-asset-uuid-a"><span class="raw-html-m2r"><a name="asset-uuid">asset_uuid</a></span></a></li>
<li><a class="reference internal" href="#a-name-faceinfo-person-info-person-info-a"><span class="raw-html-m2r"><a name="faceinfo-person-info">person_info</a></span></a></li>
<li><a class="reference internal" href="#a-name-faceinfo-photo-photo-a"><span class="raw-html-m2r"><a name="faceinfo-photo">photo</a></span></a></li>
<li><a class="reference internal" href="#a-name-mwg-rs-area-mwg-rs-area-a"><span class="raw-html-m2r"><a name="mwg-rs-area">mwg_rs_area</a></span></a></li>
<li><a class="reference internal" href="#a-name-mpri-reg-rect-mpri-reg-rect-a"><span class="raw-html-m2r"><a name="mpri-reg-rect">mpri_reg_rect</a></span></a></li>
<li><a class="reference internal" href="#a-name-face-rect-face-rect-a"><span class="raw-html-m2r"><a name="face-rect">face_rect()</a></span></a></li>
<li><a class="reference internal" href="#a-name-center-center-a"><span class="raw-html-m2r"><a name="center">center</a></span></a></li>
<li><a class="reference internal" href="#a-name-size-pixels-size-pixels-a"><span class="raw-html-m2r"><a name="size-pixels">size_pixels</a></span></a></li>
<li><a class="reference internal" href="#a-name-roll-pitch-yaw-roll-pitch-yaw-a"><span class="raw-html-m2r"><a name="roll-pitch-yaw">roll_pitch_yaw()</a></span></a></li>
<li><a class="reference internal" href="#a-name-roll-roll-a"><span class="raw-html-m2r"><a name="roll">roll</a></span></a></li>
<li><a class="reference internal" href="#a-name-pitch-pitch-a"><span class="raw-html-m2r"><a name="pitch">pitch</a></span></a></li>
<li><a class="reference internal" href="#a-name-yaw-yaw-a"><span class="raw-html-m2r"><a name="yaw">yaw</a></span></a></li>
<li><a class="reference internal" href="#additional-properties">Additional properties</a></li>
<li><a class="reference internal" href="#a-name-faceinfo-asdict-asdict-a"><span class="raw-html-m2r"><a name="faceinfo-asdict">asdict()</a></span></a></li>
<li><a class="reference internal" href="#a-name-faceinfo-json-json-a"><span class="raw-html-m2r"><a name="faceinfo-json">json()</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-commentinfo-commentinfo-a"><span class="raw-html-m2r"><a name="commentinfo">CommentInfo</a></span></a></li>
<li><a class="reference internal" href="#a-name-likeinfo-likeinfo-a"><span class="raw-html-m2r"><a name="likeinfo">LikeInfo</a></span></a></li>
<li><a class="reference internal" href="#a-name-adjustmentsinfo-adjustmentsinfo-a"><span class="raw-html-m2r"><a name="adjustmentsinfo">AdjustmentsInfo</a></span></a></li>
<li><a class="reference internal" href="#a-name-phototables-phototables-a"><span class="raw-html-m2r"><a name="phototables">PhotoTables</a></span></a></li>
<li><a class="reference internal" href="#a-name-raw-photos-raw-photos-a"><span class="raw-html-m2r"><a name="raw-photos">Raw Photos</a></span></a><ul>
<li><a class="reference internal" href="#raw-related-attributes">Raw-Related Attributes</a></li>
<li><a class="reference internal" href="#a-name-example-example-a"><span class="raw-html-m2r"><a name="Example">Example</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-template-system-template-system-a"><span class="raw-html-m2r"><a name="template-system">Template System</a></span></a></li>
<li><a class="reference internal" href="#a-name-exiftool-exiftool-a"><span class="raw-html-m2r"><a name="exiftool">ExifTool</a></span></a><ul>
<li><a class="reference internal" href="#exiftool-methods">ExifTool methods</a></li>
<li><a class="reference internal" href="#implementation-note">Implementation Note</a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-photoexporter-photoexporter-a"><span class="raw-html-m2r"><a name="photoexporter">PhotoExporter</a></span></a><ul>
<li><a class="reference internal" href="#a-name-photoexporter-export-export-dest-filename-none-options-optional-exportoptions-none-exportresults-a"><span class="raw-html-m2r"><a name="photoexporter-export">export(dest, filename=None, options: Optional[ExportOptions]=None) -> ExportResults</a></span></a></li>
<li><a class="reference internal" href="#a-name-exportoptions-exportoptions-a"><span class="raw-html-m2r"><a name="ExportOptions">ExportOptions</a></span></a></li>
<li><a class="reference internal" href="#a-name-exportresults-exportresults-a"><span class="raw-html-m2r"><a name="ExportResults">ExportResults</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-exifwriter-exifwriter-a"><span class="raw-html-m2r"><a name="exifwriter">ExifWriter</a></span></a></li>
<li><a class="reference internal" href="#a-name-sidecarwriter-sidecarwriter-a"><span class="raw-html-m2r"><a name="sidecarwriter">SidecarWriter</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosalbum-photosalbum-a"><span class="raw-html-m2r"><a name="photosalbum">PhotosAlbum</a></span></a></li>
<li><a class="reference internal" href="#a-name-textdetection-text-detection-a"><span class="raw-html-m2r"><a name="textdetection">Text Detection</a></span></a></li>
<li><a class="reference internal" href="#a-name-comparelibraries-compare-libraries-a"><span class="raw-html-m2r"><a name="comparelibraries">Compare Libraries</a></span></a><ul>
<li><a class="reference internal" href="#a-name-compare-photos-libraries-compare-photos-libraries-a"><span class="raw-html-m2r"><a name="compare-photos-libraries">compare_photos_libraries()</a></span></a></li>
<li><a class="reference internal" href="#a-name-photosdbdiff-photosdbdiff-a"><span class="raw-html-m2r"><a name="PhotosDBDiff">PhotosDBDiff</a></span></a></li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-utility-functions-utility-functions-a"><span class="raw-html-m2r"><a name="utility-functions">Utility Functions</a></span></a><ul>
<li><a class="reference internal" href="#a-name-get-system-library-path-get-system-library-path-a"><span class="raw-html-m2r"><a name="get-system-library-path">get_system_library_path()</a></span></a></li>
<li><a class="reference internal" href="#a-name-get-last-library-path-get-last-library-path-a"><span class="raw-html-m2r"><a name="get-last-library-path">get_last_library_path()</a></span></a></li>
<li><a class="reference internal" href="#a-name-list-photo-libraries-list-photo-libraries-a"><span class="raw-html-m2r"><a name="list-photo-libraries">list_photo_libraries()</a></span></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#a-name-additional-examples-additional-examples-a"><span class="raw-html-m2r"><a name="additional-examples">Additional Examples</a></span></a></li>
</ul>
</li>
</ul>

          </div>
        </div>
      </div>
      
      
    </aside>
  </div>
</div><script src="_static/documentation_options.js?v=63568c49"></script>
    <script src="_static/doctools.js?v=9bcbadda"></script>
    <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="_static/scripts/furo.js?v=46bd48cc"></script>
    <script src="_static/clipboard.min.js?v=a7894cd8"></script>
    <script src="_static/copybutton.js?v=f281be69"></script>
    </body>
</html>